Delphi 自带的 THttpClient 是一个很好的 Http/Https 协议的跨平台实现,不过,现在的版本功能有些地方封装的还是不太合理,造成使用中存在一些不便。比如,我们从一个网址通过 HTTP 302 等跳转到另一个网址时,无法对跳转的过程进行精细控制,也无法获取到跳转后的目标地址。本文给大家提供一种方法来处理这个跳转的问题,直接看代码:
procedure TForm1.Button1Click(Sender: TObject); var AHttp: THttpClient; AResp: IHttpResponse; I, AMaxRedirectTimes: Integer; AUrl: String; begin AHttp := THttpClient.Create; AHttp.HandleRedirects := False; AUrl := 'http://www.csdn.com'; AMaxRedirectTimes := 10; I := 0; repeat AResp := AHttp.Get(AUrl); if Assigned(AResp) then begin if ((AResp.StatusCode >= 301) and (AResp.StatusCode <= 304)) or (AResp.StatusCode = 307) then begin AUrl := TURI.PathRelativeToAbs(AResp.GetHeaderValue('Location'), TURI.Create(AUrl)); Inc(I); if I < AMaxRedirectTimes then continue; end else Break; end else Break; until 1 > 2; ShowMessage(AUrl); FreeAndNil(AHttp); end;
上面的代码的核心不让 THttpClient 自动处理跳转,改由我们捕获 30x 跳转代码来控制跳转的过程,通过 AMaxRedirectTimes 来控制最多跳转的次数,防止页面不停的跳来跳去,陷入死循环。上面的代码的结果 AUrl 的值会是 http://www.csdn.net,符合实际的跳转结果。剩下的大家看代码吧,看不懂的在群里问。
【补充】
群友 dragOn 提供了一个更好的解决办法,通过 IHttpRequest 对象来获取到相关的信息,感谢 dragOn:
var Http: THttpClient; Request: IHTTPRequest; begin Http := THTTPClient.Create; try Request := Http.GetRequest(sHTTPMethodHead, 'http://pro.25pp.com/download/25pp_wdjgw/8009'); Http.Execute(Request, nil, nil); ShowMessage(Request.URL.ToString); finally Http.Free; end; end;