Delphi indy获取页面内容

时间:2017-02-20 22:53:36

标签: delphi indy

我在网上看过很多例子,但我无法理解为什么我的代码无效。

我的网址如下:

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不可接受

2 个答案:

答案 0 :(得分:1)

HTTP错误406 Not acceptable通常意味着服务器无法使用客户端所需的内容类型进行响应。服务器和客户端都需要根据需要适当地使用MIME类型。在这种情况下,客户端的Accept标头应该提供所需的响应类型,并且您的服务器也应该响应相同的响应。在您的情况下,Content-Type很可能是text/plain

长话短说,您的客户端期望服务器未在其响应中显式返回的MIME类型。问题可能在任何一方,或两者兼而有之。

  1. 您客户的Accept标头必须提供您期望和需要的MIME类型。具体为AcceptAccept-CharsetAccept-LanguageAccept-Encoding。默认情况下,在Indy TIdHTTP中,这些标头应该基本上接受任何内容,假设这些标头尚未被覆盖。 Accept标头默认设置为text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q‌​=0.8,其中*/*为任何MIME类型打开了大门。
  2. 您的服务器的响应Content-Type必须是提供的MIME类型之一,以及客户端所需的响应格式。您的HTTP服务器可能未在其响应中提供相应的Content-Type。如果服务器响应*/*过滤器中的任何内容(应该表示所有内容),则客户端将接受它(假设服务器以text/plain响应)。如果服务器使用无效的内容类型(例如textplain)进行响应,则可能会被拒绝。

答案 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调试器日志:

enter image description here