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;
