我有一个网址在所有浏览器中运行良好(5台在2台计算机上测试),但是如果我尝试使用Indy Http客户端的Get()获取页面内容,则返回错误代码404,找不到页面。这是最新的Indy SVN版本(4985)。
为什么此Web服务器会返回Indy的代码404,但每个浏览器的代码为200?
我怀疑这可能是Indy中的一个错误,因为URL中的“#”字符(Indy在#之后切断了所有内容)。如果是这样,有没有办法解决这个问题。也许用转义代码替换#char?
这是我的示例代码。所需要的只是带有Indy组件的Delphi以及带有按钮和备忘录的表单。
procedure TForm1.Button1Click(Sender: TObject);
var HTTPCLIENT1: TIdHTTP;
begin
try
try
HTTPCLIENT1 := TIdHTTP.Create(nil);
Memo1.Clear;
with HTTPCLIENT1 do
begin
HandleRedirects := True;
Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31';
Memo1.Text := Get('http://www.visionofhumanity.org/gpi-data/#/2011/scor/');
Caption := ResponseText;
end;
except
On e: Exception do
begin
Memo1.Lines.Add('Exception: '+e.Message);
end;
end;
finally
HTTPCLIENT1.Free;
end;
end;
答案 0 :(得分:3)
你的怀疑是正确的。您已在请求中包含地址的#
部分。浏览器不会这样做,因为该部分是为页内导航保留的。服务器不知道这一点,因此它尝试获取与您提供的完整 URL相对应的资源,包括#
以及之后的所有内容。没有任何匹配,因此它以状态404失败。
要么像浏览器那样做,要么在将请求发送到服务器之前从URL中删除该部分,要么将Indy更新为修订版4987,以便它自动发生。仅仅逃脱角色将继续产生404状态。
答案 1 :(得分:3)
#
是网址中的保留字符。如果要在URL中使用保留字符,则需要对它们进行URL编码。 TIdHTTP
不会为您做到这一点。它要求您传入已编码的网址,但您传入的是未编码的网址。由于#
未编码,因此会将其视为锚点并被剥离,因此您实际上是在请求http://www.visionofhumanity.org/gpi-data/
,而是请回复404。
#
已被网址编码为%23
,因此请使用:
Memo1.Text := Get('http://www.visionofhumanity.org/gpi-data/%23/2011/scor/');
或者这个:
Memo1.Text := Get(TIdURI.URLEncode('http://www.visionofhumanity.org/gpi-data/#/2011/scor/'));
击> <击> 撞击>
更新:我追查了这个问题。这是另一个TIdURI
解析错误,这次涉及在/
字符后面加上#
个字符。 TIdURI
在检查/
字符之前检查#
个字符,因此该网址的锚点部分最终位于TIdURI.Path
属性中(之前它已经结束了TIdURI.Params
属性),从而提交给服务器。我已经检查了一个新的修复程序(SVN rev 4987)。