我在网上看过很多例子,但我无法理解为什么我的代码无效。
我的网址如下:
http://www.domain.com/confirm.php?user=USERNAME&id=THEID
confirm.php
是一个对MySQL数据库进行一些检查的页面,然后页面的唯一输出是0或-1(真或假):
<?php
//long code...
if ( ... ) {
echo "0"; // success!
die();
} else {
echo "-1"; // fail!
die();
}
?>
我的Delphi FireMonkey应用程序必须打开上面的URL,传递用户名和ID,然后读取页面的结果。结果只有-1或0.这就是代码。
//I have created a subclass of TThread
procedure TRegister.Execute;
var
conn: TIdHTTP;
res: string;
begin
inherited;
Queue(nil,
procedure
begin
ProgressLabel.Text := 'Connecting...';
end
);
//get the result -1 or 0
try
conn := TIdHTTP.Create(nil);
try
res := conn.Get('http://www.domain.com/confirm.php?user='+FUsername+'&id='+FPId);
finally
conn.Free;
end;
except
res := 'error!!';
end;
Queue(nil,
procedure
begin
ProgressLabel.Text := res;
end
);
end;
res
的值始终为error!!
且从不-1或0.我的代码在哪里错了?从on E: Exception do
捕获的错误是:
HTTP / 1.1 406不可接受
答案 0 :(得分:1)
HTTP错误406 Not acceptable
通常意味着服务器无法使用客户端所需的内容类型进行响应。服务器和客户端都需要根据需要适当地使用MIME类型。在这种情况下,客户端的Accept
标头应该提供所需的响应类型,并且您的服务器也应该响应相同的响应。在您的情况下,Content-Type
很可能是text/plain
。
长话短说,您的客户端期望服务器未在其响应中显式返回的MIME类型。问题可能在任何一方,或两者兼而有之。
Accept
标头必须提供您期望和需要的MIME类型。具体为Accept
,Accept-Charset
,Accept-Language
,Accept-Encoding
。默认情况下,在Indy TIdHTTP
中,这些标头应该基本上接受任何内容,假设这些标头尚未被覆盖。 Accept
标头默认设置为text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
,其中*/*
为任何MIME类型打开了大门。Content-Type
必须是提供的MIME类型之一,以及客户端所需的响应格式。您的HTTP服务器可能未在其响应中提供相应的Content-Type
。如果服务器响应*/*
过滤器中的任何内容(应该表示所有内容),则客户端将接受它(假设服务器以text/plain
响应)。如果服务器使用无效的内容类型(例如text
或plain
)进行响应,则可能会被拒绝。答案 1 :(得分:1)
我找到了使用System.Net.HttpClient
的解决方案。我可以简单地使用这个功能
function GetURL(const AURL: string): string;
var
HttpClient: THttpClient;
HttpResponse: IHttpResponse;
begin
HttpClient := THTTPClient.Create;
try
HttpResponse := HttpClient.Get(AURL);
Result := HttpResponse.ContentAsString();
finally
HttpClient.Free;
end;
end;
这是有效的,并按我的预期给出-1和0。为了得到一个工作代码的例子,我测试了这个:
procedure TForm1.Button1Click(Sender: TObject);
function GetURL(const AURL: string): string;
var
HttpClient: THttpClient;
HttpResponse: IHttpResponse;
begin
HttpClient := THTTPClient.Create;
try
HttpResponse := HttpClient.Get(AURL);
Result := HttpResponse.ContentAsString();
finally
HttpClient.Free;
end;
end;
function GetURLAsString(const aURL: string): string;
var
lHTTP: TIdHTTP;
begin
lHTTP := TIdHTTP.Create;
try
Result := lHTTP.Get(aURL);
finally
lHTTP.Free;
end;
end;
begin
Memo1.Lines.Add(GetURL('http://www.domain.com/confirm.php?user=user&id=theid'));
Memo1.Lines.Add(GetURLAsString('http://www.domain.com/confirm.php?user=user&id=theid'))
end;
end.
第一个功能完美无缺,但Indy引发异常 HTTP / 1.1 406不可接受。似乎Indy无法自动处理页面的内容类型。在这里,您可以看到REST调试器日志: