【问题标题】:Delphi: download a file with URL ForwardingDelphi:使用 URL 转发下载文件
【发布时间】:2012-01-15 06:24:43
【问题描述】:

我有一个带有 URL 转发(伪装)到另一个站点的免费域名。

如果我在浏览器的网址中输入http://my.com/1.zip,它会转到http://his.com/1.zip 并下载一个文件。

如何使用 Indy TIdHTTP (Delphi XE2) 做同样的事情。浏览器和我一开始遇到 404 错误,但后来他们以某种方式下载了除我之外的文件。

我需要使用第一个链接,但实际上是从另一个站点下载的。例如。第一个站点有一个 xxx.zip 文件。我想去http://my.com/xxx.zip,但实际上是从http://his.com/xxx.zip(文件存储的地方)下载。

谢谢!

编辑:

我将HandleRedirects 设置为true,分配了CookieManager(我已经看到了这个问题Indy - IdHttp how to handle page redirects?)。

尝试在你的 Delphi 中下载这个http://liga-updates.ua.tc/GDI+.zip

【问题讨论】:

  • 您是否尝试过使用工具(Fiddler)来查看初始请求的实际 HTTP 标头?
  • 没有标头(在 HTTP 分析器中)。请查看我编辑的问题
  • 你看过网页源码吗?
  • 页面来源是关键。 URL 隐藏通常是通过使用 HTML 框架来完成的。浏览器地址栏显示顶级框架集的域,然后内部框架显示来自另一个域的内容。因此,您必须下载伪装 URL 的内容并对其进行解析,以确定被伪装内容的真实 URL。

标签: delphi url indy forwarding idhttp


【解决方案1】:

有问题的网站正在返回一个 HTTP 404 响应,其中的 HTML 页面包含一个加载真实 URL 的 <iframe>。默认情况下,404 回复将导致 TIdHTTP 引发 EIdHTTPProtocolException 异常。可以通过EIdHTTPProtocolException.ErrorMessage 属性访问回复的内容(HTML)。

例如:

procedure TForm1.Button1Click(Sender: TObject); 
var 
  Http: TIdHttp; 
  URL, Filename: string; 
  FS: TFileStream; 
  ...
begin 
  Filename := 'C:\path\GDI+.zip';
  URL := 'http://liga-updates.ua.tc/GDI+.zip'; 

  FS := TFileStream.Create(Filename, fmCreate); 
  try
    try
      Http := TIdHttp.Create(nil); 
      try 
        try
          Http.Get(URL, FS); 
        except 
          on E: EIdHTTPProtocolException do begin
            if E.ErrorCode <> 404 then raise;
            URL := ParseIFrameURLFromHTML(E.ErrorMessage);
            if URL = '' then raise;
            Http.Get(URL, FS); 
          end;
        end; 
      finally 
        Http.Free; 
      end; 
    finally 
      FS.Free; 
    end; 
  except
    DeleteFile(Filename);
    ShowMessage('Unable to download file.');
    Exit;
  end;
  ShowMessage('Downloaded OK'); 
end;

【讨论】:

  • 太糟糕了 OP 没有响应。这个解决方案很完美。
【解决方案2】:

http://liga-updates.ua.tc 似乎是基于 404 错误重定向到自定义页面(由网络服务器内部使用)。

尝试对那里的任何资源执行 http head:它将返回 404 和 HTML 响应。 该响应包含一个iframe 元素和src 到真正的下载文件。 基于此,我写了一个小代码。

我使用了THttpCli,因为 TIdHttp 似乎不会返回状态为 404 的“有效”响应(无论如何我的 D5 版本中都没有)。

uses HttpProt;

procedure TForm1.Button1Click(Sender: TObject);
const
  IFRAME_SRC = '<iframe src="';
var
  HttpCli: THttpCli;
  S, URL, FileName: string;
  I: Integer;
  FS: TFileStream;
begin
  URL := 'http://liga-updates.ua.tc/GDI+.zip';

  HttpCli := THttpCli.Create(nil);
  try
    HttpCli.URL := URL;
    HttpCli.MultiThreaded := True;
    try
      HttpCli.Get;
    except
      // this will always be 404 for this domain (test from outside the IDE)
    end;
    S := HttpCli.LastResponse; // THttpCli returns valid response when status 404
    // extract IFRAME src
    I := Pos(IFRAME_SRC, S);
    if I <> 0 then
    begin
      Delete(S, 1, I + Length(IFRAME_SRC) - 1);
      URL := Copy(S, 1, Pos('"', S) - 1);
      HttpCli.URL := URL;
      FileName := ExtractFileName(StringReplace(URL, '/', '\', [rfReplaceAll]));
      FS := TFileStream.Create(FileName, fmCreate);
      try
        HttpCli.RcvdStream := FS;
        try
          HttpCli.Get;
          ShowMessage('Downaloded OK');
        except
          ShowMessage('Unable to download file.');
        end;
      finally
        FS.Free;
      end;
    end
    else
      ShowMessage('Unable to extract download information.');
  finally
    HttpCli.Free;
  end;
end;

【讨论】:

  • HTTP 404 响应不执行重定向。重定向由带有 HTTP Location 标头的 HTTP 3xx 回复(304 除外)执行。
  • 404 错误重定向不是响应重定向。它由 Web 服务器内部使用。这是example
  • 这仍然不是重定向。在这种情况下,网络服务器返回一个标准的404 回复,其中包含一个 HTML 页面作为其内容,并且该 HTML 包含一个在内部加载另一个 URL 的框架。大多数网络服务器不以这种方式处理自定义404 页面。他们加载帐户所有者的自定义404 页面,根据需要对其进行解析(以处理服务器端脚本),并将结果作为404 回复的内容直接提供。
  • 这个术语叫做 404 重定向(google it)。同样,它不是返回给客户端的标头 3xx 重定向。但这只是术语。 “网络服务器正在返回一个标准的 404 回复,其中包含一个 HTML 页面作为其内容”——这是真的,而且正是我的代码所做的。尝试使用TIdHttp 阅读此内容...我不能。母鸡 THttpCli.
  • 默认情况下,404 回复将导致 TIdHTTP 引发 EIdHTTPProtocolException 异常。可以通过EIdHTTPProtocolException.ErrorMessage 属性访问回复的内容。
【解决方案3】:

试试TIdHTTP 组件的HandleRedirects 属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    相关资源
    最近更新 更多