【问题标题】:Delphi Seattle - Sending Post Request with custom body Responds bad Request 400Delphi Seattle - 发送带有自定义正文的帖子请求响应错误的请求 400
【发布时间】:2018-05-30 08:32:08
【问题描述】:

我想向外部提供者的休息服务器发送一个发布请求。我尝试过使用 Curl,一切都很完美。这是 CURL 代码:

    curl -X POST -H 'PRODUCT-KEY: SUperL0ngAndSpecialSecretCode' -H 'Content-Type: application/json' -H 'Authorization: Basic CrytedWorksalsowellwithotherget' -i 'http://myserver:8080/rest.svc/v1.0/query' --data '{
"query":"SELECT Name from Address where name like '\''%me%'\''"
}'

在 Curl 中一切正常。 我已经尝试了几个小时来让这个代码在 Delphi 中工作。这时候我的代码是这样的:

function GetSomeInformation: string;
var
  lrestrequest: TRESTRequest;
  lRestClient: TRESTClient;
  lRestResponce: TRESTResponse;
begin
  result := '';
  lRestClient := TRESTClient.Create('http://myserver:8080/rest.svc/v1.0/query');
  try
    lrestrequest := TRESTRequest.Create(nil);
    try
      lRestResponce := TRESTResponse.Create(nil);
      try
        lrestrequest.Client := lRestClient;
        lrestrequest.Response := lRestResponce;
        lrestrequest.Method := rmPost;
        lrestrequest.Params.AddItem('PRODUCT-KEY',
          'SUperL0ngAndSpecialSecretCode',
          TRESTRequestParameterKind.pkHTTPHEADER);
        lrestrequest.Params.AddItem('Content-Type', 'application/json',
          TRESTRequestParameterKind.pkHTTPHEADER);
        lrestrequest.Params.AddItem('query',
          ansitoutf8('SELECT Name from Address where Name like ' +
          quotedstr('%me%')), TRESTRequestParameterKind.pkREQUESTBODY);
        lrestrequest.Execute;
        if not lRestResponce.Status.Success then
          showmessage(lRestResponce.StatusText + ' ' +
            inttostr(lRestResponce.StatusCode))
        else
          result := lRestResponce.Content;
      finally
        lRestResponce.Free;
      end;
    finally
      lrestrequest.Free
    end;
  finally
    lRestClient.Free;
  end;
end;

我不知道下一步该怎么做才能完成工作?我可以更好地调试问题的任何想法或方法。

--更新

好的,我使用 Wireshark 检查 Post 命令之间是否有任何差异,看起来 Delphi 忽略或破坏了我的 Header。 在 Wireshark sn-p 中有一个 Value Content-Type。应该是

Content-Type: application/json

但使用 Delphi 我得到了

Content-Type: application%2Fjson, application/x-www-form-urlencoded

我也想念产品键值。 有什么建议吗?

【问题讨论】:

  • 抱歉忘记添加一些信息。身份验证与基本身份验证器一起使用,在我的“真实”项目中,我使用 VCL 表单上的组件,我使用 GET 值和身份验证完成了其他请求,效果很好。
  • 使用 wireshark/fiddler 将 CURL 请求与 TRESTRequest 请求进行比较,看看有什么不同。

标签: rest delphi post delphi-10-seattle


【解决方案1】:

您必须在 TRESTRequest 的 Method 属性中指定请求的类型

lRESTRequest.Method := TRESTRequestMethod.rmPost

Delphi 附带代码示例!

http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/REST.RESTDemo_Sample

【讨论】:

  • 对不起,Request中的Method当然设置为rmPost。我在原始帖子中更改了它
【解决方案2】:

经过一些研究和一些 Wireshark,我至少在这里完成了我的工作,这是我将参数放入请求的方式。

function GetSomeInformation: string;
var
  lrestrequest: TRESTRequest;
  lRestClient: TRESTClient;
  lRestResponce: TRESTResponse;
begin
  result := '';
  lRestClient := TRESTClient.Create('http://myserver:8080/rest.svc/v1.0/query');
  try
    lrestrequest := TRESTRequest.Create(nil);
    try
      lRestResponce := TRESTResponse.Create(nil);
      try
        lrestrequest.Client := lRestClient;
        lrestrequest.Response := lRestResponce;
        RESTRequest1.Params.Clear;
        RESTRequest1.Method:=rmpost;
        RESTResponse1.RootElement := '';
        lparam := RESTRequest1.Params.AddItem;
        lparam.name := 'PRODUCT-KEY';
        lparam.Value := 'SpecialKeyButWithSomeTrickyCharsLike==';
        lparam.ContentType := ctNone;
        lparam.Kind := pkHTTPHEADER;
        //This one is Important otherwise the '==' will get url encoded
        lparam.Options := [poDoNotEncode];

        lparam := RESTRequest1.Params.AddItem;
        lparam.name := 'data';
        lparam.Value := '{"query":"' + SelectString + '"}';
        lparam.ContentType := ctAPPLICATION_JSON;
        lparam.Kind := pkGETorPOST;
        lrestrequest.Execute;
        if not lRestResponce.Status.Success then
          showmessage(lRestResponce.StatusText + ' ' +
            inttostr(lRestResponce.StatusCode))
        else
          result := lRestResponce.Content;
      finally
        lRestResponce.Free;
      end;
    finally
      lrestrequest.Free
    end;
  finally
    lRestClient.Free;
  end;
end;

感谢支持!

PJM

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多