【问题标题】:Problems using Indy10 to access a Mashape API Service使用 Indy10 访问 Mashape API 服务的问题
【发布时间】:2014-07-09 00:29:44
【问题描述】:

我正在尝试使用 Delphi XE3 和 Indy10 编写一个使用 Mashape API 服务的客户端应用程序,但我遇到了一些障碍。

这是我尝试过的:

我在表单上放置了TIdHTTPTIdSSLIOHandlerSocketOpenSSL 组件,并使用TIdHTTP.IOHandler 属性将它们链接在一起。然后我在我的表单上放置了一个按钮和备忘录,并在按钮OnClick event 上放置了以下代码:

procedure TForm1.Button2Click(Sender: TObject);
begin
 IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
 IdHTTP1.Request.CustomHeaders.AddValue('X-Mashape-Key: ','<my_api_key>');
 Memo1.Lines.Text := IdHTTP1.Get('https://hbrd-v1.p.mashape.com/anime/log-horizon');
end;

然后我启动我的应用程序,当我按下按钮时,应用程序将等待片刻,然后吐出 HTTP/1.1 403 Forbidden 错误消息。第二次按下按钮将产生HTTP/1.1 500 Internal Service Error 消息。

我已经检查过我的系统上是否有所需的 SSL 库文件,并且确实有,而且我已经一次又一次地测试了我的凭据,它们似乎是正确的,而且我知道 URL 是正确的,所以我我的代码中必须缺少某些内容才能导致显示这些错误。我希望在这方面有更多经验的人可以提供一些建议。

更新:这是有效的TRESTClient 代码:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IPPeerClient, Vcl.StdCtrls,
  REST.Response.Adapter, REST.Client, Data.Bind.Components,
  Data.Bind.ObjectScope;

type
  TForm1 = class(TForm)
    RESTClient1: TRESTClient;
    RESTRequest1: TRESTRequest;
    Button1: TButton;
    Memo1: TMemo;
    RESTResponse1: TRESTResponse;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 RESTClient1.BaseURL := 'https://hbrd-v1.p.mashape.com/anime/log-horizon';
 RESTRequest1.Execute;
 Memo1.Lines.Text := RESTResponse1.Content;

// The only thing not shown here is the RESTRequest1.Params which are
// Name: 'X-Mashape-Key'
// Value: 'my-api-key'
// Kind: pkHTTPHEADER
// Everything else is included here which isn't much.
end;

end.

我想对 TIdHTTP 做同样的事情。

【问题讨论】:

    标签: delphi ssl indy mashape


    【解决方案1】:

    如果不看到来回传递的实际 HTTP 消息,就很难知道实际发生了什么。当 HTTP 响应指示错误时,会引发 EIdHTTPProtocolException 异常,并且其 ErrorMessage 属性包含服务器响应的正文。它是否向您说明了错误发生的原因?

    但是,您确实需要更改此设置:

    IdHTTP1.Request.CustomHeaders.AddValue('X-Mashape-Key: ','<my_api_key>');
    

    到这里:

    IdHTTP1.Request.CustomHeaders.Values['X-Mashape-Key'] := '<my_api_key>';
    

    并摆脱程序化的IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1; 分配,因为您已经在表单设计器中处理了它。

    除此之外,403 错误意味着服务器不接受您的凭据。我没有看到您在代码中为 TIdHTTP.Request.UsernameTIdHTTP.Request.Password 属性分配任何凭据,您是在表单设计器中这样做的吗?

    TIdHTTP 使用插件系统来处理 HTTP 身份验证方案。如果服务器允许BASIC 身份验证,您可以将TIdHTTP.Request.BasicAuthentication 属性设置为true,以便在没有其他身份验证方案可用时使用BASIC 作为默认值。您可以使用TIdHTTP.OnSelectAuthorization 事件来查看服务器实际支持的身份验证。

    如果服务器想要非BASIC 身份验证,您需要将相关的IdAuthentication... 添加到您的uses 子句以启用该插件。例如,IdAuthenticationDigest 用于DIGEST 身份验证,IdAuthenticationNTLM 用于NTLM 身份验证等。或者,添加IdAllAuthentications 单元以启用所有插件。

    如果您需要使用 Indy 不支持的 HTTP 身份验证(例如OATH),您可以:

    1. 使用TIdHTTP.Request.CustomHeaders.Values['Authorization']手动提供相关凭证数据。

    2. 实现一个自定义的TIdAuthentication派生类,并将其实例分配给TIdHTTP.Request.Authorization属性,或其类类型分配给TIdHTTP.OnSelectAuthorization事件的VAuthenticationClass参数。

    【讨论】:

    • 我根据您的指示进行了更改,即使在将我的用户名和密码添加到请求中(顺便说一句,它们不是必需的)并检查基本身份验证是 TRUE 还是 FALSE 之后也是如此。错误仍然发生。对我来说奇怪的是,我在 TRestClient 控件中使用了完全相同的值,它们工作得很好,但是它们对我的需求来说太慢了,这就是为什么我想使用 INDY 来代替,希望它会更快。我不确定现在如何进行。
    • TRESTClient 在内部使用 TIdHTTP。如果您捕获由TRESTClient 发送的原始HTTPS 请求(Fiddler 支持HTTPS,并且TRESTClient 具有ProxyServer/ProxyPort 属性),您可以配置TIdHTTP 以根据需要复制请求值。或者,出示您的TRESTClient 代码,我会为您翻译成TIdHTTP
    • 这是来自 TRESTClient 版本的 Unit 的 Pastebin:pastebin.com/7HitQDCX 我希望这就是您正在寻找的东西,它非常简单,但它有效,只是在获取结果时有点慢。
    • 为了将来参考,请勿将您的代码发布到 pastebin 或任何其他外部站点。将代码直接嵌入您的问题中。我已经为你更新了你的问题,很快就会给你一个TIdHTTP 翻译。
    • 只是签到看看你是否设法让它与 INDY 一起工作,就像它与 Rest 客户端一样?如果您需要我的 api 密钥进行测试,我可以与您分享。
    猜你喜欢
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 2012-08-22
    • 2022-01-15
    相关资源
    最近更新 更多