我在向网站发送get请求之前尝试更改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
标头,Host
标头也会再次更改为stackoverflow.com
。我究竟做错了什么?我想将请求标题更改为example.com
。
由于
答案 0 :(得分:4)
不幸的是,没有选项可以指定自定义Host
标头,该标头指定的主机名与URL中指定的主机名不同。 URL具有优先权。您在Request.Host
甚至Request.CustomHeaders
中指定的任何主机名都会被URL中的主机名覆盖。
如果URL中的主机名未在DNS中注册,则无法使用任何 Web浏览器或大多数HTTP库(包括TIdHTTP
)访问该主机名。虽然HTTP协议本身定义了Host
标头的工作方式,但当前的Web浏览器技术使用了URL中的主机名,TIdHTTP
也是如此。因此,首先使用未使用DNS注册的主机名的网站没有意义,因为大多数现代客户端系统都无法检索它。需要DNS将URL的主机名转换为IP地址,然后将相同的主机名放入Host
标头。
答案 1 :(得分: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.com
至myblog.wordpress.com
而example.com
更改为anotherblog.wordpress.com
,则IdHTTP1.Get('http://myblog.wordpress.com')
我们将获得anotherblog.wordpress.com
个内容