[技巧] 使用 THttpClient 时获取跳转后的 URL

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;

 

分享到: