1

谁能指出正确的方向?我正在尝试使用新的 Bing API 执行网络搜索,但使用下面的代码,我不断收到“HTTP/1.1 400 Bad Request”。相同的请求在浏览器下运行良好(将用户名留空并在提示框中提供密码下的密钥)。

var
  IdHTTP1 : TIdHTTP;
  uri : string;
  myIOhandler : TIdSSLIOHandlerSocketOpenSSL;
begin
  myIOhandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  with myIOhandler do
  begin
      SSLOptions.Method := sslvTLSv1;
      SSLOptions.Mode := sslmUnassigned;
      SSLOptions.VerifyMode := [];
      SSLOptions.VerifyDepth := 0;
      host := '';
  end;

  IdHTTP1:= TIdHTTP.Create(nil);
  IdHTTP1.Request.UserAgent:= 'Mozilla/3.0 (compatible; IndyLibrary)';
  IdHTTP1.Request.Accept := 'text/javascript';
  IdHTTP1.Request.ContentType := 'application/json';
  IdHTTP1.Request.ContentEncoding := 'utf-8';

  IdHTTP1.HandleRedirects:= True;
  IdHTTP1.ConnectTimeout:= 10000;
  IdHTTP1.ReadTimeout:= 10000;
  IdHTTP1.Request.CacheControl := 'no-cache';
  IdHTTP1.Request.BasicAuthentication:= True;
  IdHTTP1.Request.Authentication:= TIdBasicAuthentication.Create;
  IdHTTP1.Request.Authentication.Username:= '';
  IdHTTP1.Request.Authentication.Password:= APIKey;//Encode64(APIKey);//Encode64(APIKey+':'+APIKey)
  IdHTTP1.IOHandler:= myIOHandler;

  uri:= 'https://api.datamarket.azure.com/Bing/SearchWeb/Web?'+
          'Query=%27'+ query_text +'%27&$format=JSON&$top=50&$skip=0';
  s:= IdHTTP1.Get(uri);  

MS文档很差。

4

2 回答 2

3

TIdHTTPBasic自动为您处理身份验证。只需设置IdHTTP1.Request.BasicAuthentication := True然后填写IdHTTP1.Request.UsernameIdHTTP1.Request.Password属性。你不需要TIdBasicAuthentication直接处理。

如果您想支持其他身份验证,例如 NTLM,只需将相关IdAuthentication...单元或IdAllAuthentication单元添加到您的uses子句中。

You can also implement your own custom TIdAuthentication-derived class if you want to support custom authentications that Indy does not natively support. You can either call RegisterAuthenticationMethod() so TIdHTTP can use your custom class automatically, or you can use the TIdHTTP.OnSelectAuthorization event to assign the class manually on a per-request basis.

于 2012-08-01T17:20:29.027 回答
1

我认为问题在于用户名。使用基本身份验证,您需要发送如下所示的标头:

Authorization: Basic BASE64ENC(username:password)

由于在您的情况下用户名是空的,因此您实际上是在发送:

Authorization: Basic BASE64ENC(:password)

尽管文档说将用户名留空,但这仅适用于您通过浏览器访问页面时。查看文档末尾的代码示例,您会发现在许多示例中,用户名和密码都是帐户密钥:

bingContainer.Credentials = new NetworkCredential(accountKey, accountKey);

我建议你在你的代码中做同样的事情:

IdHTTP1.Request.Authentication:= TIdBasicAuthentication.Create;
IdHTTP1.Request.Authentication.Username:= APIKey;
IdHTTP1.Request.Authentication.Password:= APIKey;
于 2012-07-31T14:33:28.017 回答