Delphi:使用带有IdHTTP的Google URL Shortener - 400 Bad Request

时间:2012-08-06 12:18:58

标签: delphi api openssl idhttp

我正在尝试通过Delphi中的API访问URL Shortener(http://goo.gl/)。 但是,我得到的唯一结果是: HTTP / 1.0 400错误请求(原因:parseError)

这是我的代码(在带有 Button1 Memo1 IdHTTP1 的表单上,其中 IdSSLIOHandlerSocketOpenSSL1 为它的IOHandler。我从http://indy.fulgan.com/SSL/获得了必要的32位OpenSSL DLL,并将它们放在.exe的目录中):

procedure TFrmMain.Button1Click(Sender: TObject);
    var html, actionurl: String;
    makeshort: TStringList;
begin
try
 makeshort := TStringList.Create;

 actionurl := 'https://www.googleapis.com/urlshortener/v1/url';
 makeshort.Add('{"longUrl": "http://slashdot.org/stories"}');

 IdHttp1.Request.ContentType := 'application/json';
 //IdHTTP1.Request.ContentEncoding := 'UTF-8'; //Using this gives error 415

 html := IdHTTP1.Post(actionurl, makeshort);
 memo1.lines.add(idHTTP1.response.ResponseText);

     except on e: EIdHTTPProtocolException do
        begin
            memo1.lines.add(idHTTP1.response.ResponseText);
            memo1.lines.add(e.ErrorMessage);
        end;
    end;

 memo1.Lines.add(html);
 makeshort.Free;
end;

更新:在此示例中,我已经取消了我的API密钥(通常情况下应该可以正常运行,但是如果您想尝试使用自己的API密钥),则可以替换 actionurl 字符串     'https://www.googleapis.com/urlshortener/v1/url?key=<yourapikey>';

ParseError消息让我相信longurl在发布时可能会出现问题,但我不知道该改变什么。

我已经对此进行了一段时间的模糊测试,我确信错误就在眼前 - 我现在还没有看到它。 因此,非常感谢任何帮助!

谢谢!

2 个答案:

答案 0 :(得分:4)

正如您所发现的,TStrings方法的TIdHTTP.Post()重载版本是错误的使用方法。它发送application/x-www-form-urlencoded格式化的请求,该请求不适合JSON格式的请求。您必须使用TStream方法的TIdHTTP.Post()重载版本,例如:

procedure TFrmMain.Button1Click(Sender: TObject); 
var
  html, actionurl: String; 
  makeshort: TMemoryStream; 
begin 
  try
    makeshort := TMemoryStream.Create; 
    try 
      actionurl := 'https://www.googleapis.com/urlshortener/v1/url'; 
      WriteStringToStream(makeshort, '{"longUrl": "http://slashdot.org/stories"}', IndyUTF8Encoding); 
      makeshort.Position := 0;

      IdHTTP1.Request.ContentType := 'application/json'; 
      IdHTTP1.Request.Charset := 'utf-8';

      html := IdHTTP1.Post(actionurl, makeshort); 
    finally
      makeshort.Free; 
    end;

    Memo1.Lines.Add(IdHTTP1.Response.ResponseText); 
    Memo1.Lines.Add(html); 
  except
    on e: Exception do 
    begin 
      Memo1.Lines.Add(e.Message); 
      if e is EIdHTTPProtocolException then
        Memo1.lines.Add(EIdHTTPProtocolException(e).ErrorMessage); 
    end; 
  end; 
end; 

答案 1 :(得分:2)

来自网址缩短器API docs

  

您的应用程序发送给Google URL Shortener API的每个请求   需要向Google确定您的申请。有两种方法可以   识别您的应用程序:使用OAuth 2.0令牌(也是   授权请求)和/或使用应用程序的API密钥。

您的示例不包含OAuth或API密钥身份验证的代码。

要使用API​​密钥进行身份验证,文档很明确:

  

拥有API密钥后,您的应用程序可以附加查询   参数key =所有请求URL的yourAPIKey。