1

我正在尝试Host在向网站发送获取请求之前更改标头。我使用以下代码做到这一点:

IdHTTP1.Request.HOST := 'example.com';
memo1.Text := IdHTTP1.Get('http://stackoverflow.com');
showmessage(IdHTTP1.Request.Host); // Expected to be example.com but it's stackoverflow.com 

我这里有个大问题。即使我Host在获取 URL 之前更改了标题,Host标题也会stackoverflow.com再次更改为。我究竟做错了什么?我想将请求标头更改为example.com.

谢谢

4

2 回答 2

5

不幸的是,没有选项可以指定自定义Host标头,该标头指定的主机名与 URL 中指定的主机名不同。URL 具有优先权。Request.Host您在或什至中指定的任何主机名都会Request.CustomHeaders被 URL 中的主机名覆盖。

如果 URL 中的主机名未在 DNS 中注册,您将无法使用任何Web 浏览器或大多数 HTTP 库(包括TIdHTTP. 虽然 HTTP 协议本身定义了Host标头的工作方式,但当前的 Web 浏览器技术使用 URL 中的主机名,TIdHTTP. 因此,拥有一个使用未在 DNS 中注册的主机名的网站是没有意义的,因为大多数现代客户端系统将无法检索它。需要 DNS 将 URL 的主机名转换为 IP 地址,然后将相同的主机名放入Host标头中。

于 2014-10-26T17:29:10.477 回答
0

正如 Remy Lebeau 所说,似乎没有办法指定自定义Host标题。所以我决定IdHTTP稍微修改一下代码。

IdHTTP.pas首先,我将( )复制C:\Program Files (x86)\Embarcadero\Studio\XX.0\source\Indy10\Protocols\IdHTTP.pas到我的项目目录并将其添加到我的项目中。然后在TIdCustomHTTP.PrepareRequest方法(第 1792 行)中,我更改了如下代码:

if (TextIsSame(FURI.Protocol, 'http') and (FURI.Port = IntToStr(IdPORT_HTTP))) or  {do not localize}
      (TextIsSame(FURI.Protocol, 'https') and (FURI.Port = IntToStr(IdPORT_https))) then  {do not localize}
    begin
      if FURI.Host = 'stackoverflow.com' then
        ARequest.Host := 'example.com'
      else
        ARequest.Host := FURI.Host;
    end else begin
      if FURI.Host = 'stackoverflow.com' then
        ARequest.Host := 'example.com' + ':' + FURI.Port   {do not localize}
      else
        ARequest.Host := FURI.Host + ':' + FURI.Port;    {do not localize}
    end;

我知道这不是最好的方法,修改库也不是一个好主意,但它对我有用。

因此,如果我将上面的示例更改stackoverflow.commyblog.wordpress.comexample.comanotherblog.wordpress.com我们IdHTTP1.Get('http://myblog.wordpress.com')将获得anotherblog.wordpress.com内容。

于 2014-10-26T20:52:30.203 回答