Overbyte ICS HTTPS POST

时间:2012-07-16 05:26:43

标签: delphi delphi-xe2 firemonkey indy10 cloudflare

我想在CloudFlare框架中创建一个Firemonkey客户端。对于那些不知道的人,CloudFlare可以作为任何拥有网站的人的CDN。他们有一个可用的API,和许多Web API一样,他们使用JSON和基于令牌的系统。它需要帐户电子邮件地址和帐户令牌才能访问API。它运行在HTTPS上,您可以想象,尝试通过HTTP /非SSL访问API只会产生空结果。

我想创建的应用程序将作为一体化管理工具,旨在消除我使用Web浏览器管理我的CloudFlare设置的需要。我有最基本的问题; SSL POST。请参阅,我可以通过网络浏览器提交API请求并获取结果列表(例如https://www.cloudflare.com/api_json.html?a=stats&z=DOMAIN&u=EMAIL&tkn=TOKEN - 出于显而易见的原因删除了个人详细信息),但我不确定如何获得这些相同的结果(或Firemonkey中的API的任何结果。

我已经安装了SSL Overbyte ICS,以及基本的捆绑Indy组件,但我很难开始使用它。我需要通过HTTPS / SSL将参数列表发布到https://www.cloudflare.com/api_json.html,但我很少知道从哪里开始。我已经看到了一些围绕SO的各种示例,主要是使用ICS,但我一直无法找到任何具体的发布多个参数,我应该如何格式化等等。

我尝试的一个例子是使用ICS TSSLHttpCli,将我的参数编写为单个字符串(即a=stats&z=DOMAIN&u=EMAIL&tkn=TOKEN),将其写入SendStream的{​​{1}},寻求TSSLHttpCli,设置网址(即0,0),然后调用https://www.cloudflare.com/api_json.html?方法。但是,这给了我Post。这是我尝试过的代码(虽然我用通用值替换了个人详细信息);

Connection aborted on request

var Data : AnsiString; RcvStrm, SndStrm : TMemoryStream; begin SndStrm := TMemoryStream.Create; RcvStrm := TMemoryStream.Create; Data := '?a=stats&z=MYDOMAIN&u=MYEMAIL&tkn=MYTOKEN'; SslHttpCli.SendStream := SndStrm; SslHttpCli.SendStream.Write(Data[1],Length(Data)); SslHttpCli.SendStream.Seek(0,0); Memo1.Lines.LoadFromStream(SndStrm); ShowMessage('Waiting!'); SslHttpCli.RcvdStream := RcvStrm; SslHttpCli.URL := 'https://www.cloudflare.com/api_json.html'; SslHttpCli.Post; Memo1.Lines.Clear; Memo1.Lines.LoadFromStream(RcvStrm); Memo1.Lines.Add('.....'); RcvStrm.Free; SndStrm.Free; ShowMessage('Complete!'); end; 程序只是提供一个视觉中断,所以我可以看到每次流中的数据。调用ShowMessage时,我会按预期在备忘录中收到Memo1.Lines.LoadFromStream(SndStrm);的内容。

当我打电话给Data时,我希望它能从API中添加返回结果,然后在它下面添加5个点。但是,这种情况不会发生,而且我收到的消息显然与问题有关。我假设我没有正确设置数据,但我只是不确定在尝试发布之前我应该​​如何格式化它。我甚至将Memo1.Lines.LoadFromStream(RcvStrm);以下的所有内容评论到最后,看看是否在备忘录上调用了Memo1.Lines.LoadFromStream(RcvStrm);程序,但备忘录的内容与我调用{{1}时的内容保持一致}}。最后的Clear也没有被调用。

我最初尝试使用String而不是AnsiString,但这只是输出Data的第一个字符而不是整个字符串。

可能有很多原因导致它无法正常工作(API访问的所有细节都是正确的,所以这是代码的问题),但我需要有更多经验和知识的人指出我正确的方向。

我的网络编码知识有限,到目前为止我只处理Delphi中的基本SQL和FTP。一旦我完成了这一步,我仍然需要使用已解析的JSON,但是现在,任何人都可以协助我完成这项工作,这样我就可以开始了吗?

3 个答案:

答案 0 :(得分:0)

我注意到你似乎用GET请求解决了这个问题,但我注意到你的POST请求有两个直接问题:

  1. 作为Runner建议,放下'?'在你的数据中。 '?'仅在将参数附加到GET请求中的URL时使用。

  2. 您永远不会设置HTTP请求的内容类型(应为application/x-www-form-urlencoded)。您可以使用以下代码执行此操作:

    SSLHttpCli.ContentTypePost := 'application/x-www-form-urlencoded';

  3. 只是一个有用的想法。我检查了https://www.cloudflare.com/docs/client-api.html,他们提到接受了POST请求。服务器可能会拒绝具有任何其他内容类型的请求。

    如果您需要通过POST请求联系其他API并希望使用Overbyte Components,那么只需要考虑一下。

    希望信息有用!

答案 1 :(得分:0)

尝试一下;

SndStrm := TMemoryStream.Create;
RcvStrm := TMemoryStream.Create;
Data := 'a=stats&z=MYDOMAIN&u=MYEMAIL&tkn=MYTOKEN';
SndStrm.Write(Data[1], Length(Data));
SndStrm.Seek(0, 0);
SslHttpCli.SendStream := SndStrm;

答案 2 :(得分:-1)

我只是想出来了。为了其他新的HTTP POST,这就是我所做的;

1)将TIdHTTP放到您的表单上(Indy的一部分)

2)将TIdSSLIOHandlerSocketOpenSSL放到您的表格上(也是Indy的一部分)

3)将IOHandler的{​​{1}}值设置为IdHTTP(默认名称)

4)将IdSSLIOHandlerSocketOpenSSL1放到您的表单上(在示例中,它称为TMemo

5)使用下一个块中的代码在事件处理程序中进行POST(例如button.onclick);

Memo1

随意删除var Params, RcvStrng : TStringStream; begin RcvStrng := TStringStream.Create; Params := TStringStream.Create; Params.WriteString('a=stats'); Params.WriteString('z=MYDOMAIN'); Params.WriteString('u=MYEMAIL'); Params.WriteString('tkn=MYTOKEN'); IdHTTP.Post('https://www.cloudflare.com/api_json.html',Params,RcvStrng); ShowMessage('Waiting!'); Memo1.Lines.Clear; Memo1.Text := RcvStrng.DataString; Params.Free; ShowMessage('Complete!'); end; 程序。还有一些工作要做,因为我从API得到了错误响应,但它现在在工作范围内(而不是错误输出)。其余API请求的格式类似,只需添加,删除或修改ShowMessage即可使用您需要发送的请求。

不需要ParamsSynapse或任何其他“非捆绑”组件来使其正常工作,因为Indy完美地完成了这项工作,假设您设置了IOHandler并使用{{1正确的。

我很高兴任何人都可以通过CloudFlare特有的额外点来为此做出贡献,并会尝试适当地编辑答案。

CloudFlare特定备注

我对此进行了更多调查,对于CloudFlare,我必须直接发布到完全限定的URL(即带有以下参数的API URL,与通过浏览器访问它的方式完全相同)或者在原始问题中提到; ICS)。其余代码保持不变,但可以简单地提交一个空StringStream来代替TStringStream。在没有指定https://www.cloudflare.com/api_json.html?a=stats&z=DOMAIN&u=EMAIL&tkn=TOKEN的情况下提交不同的Params重载版本只会返回没有结果。