【问题标题】:Delphi HTTP Post JSONDelphi HTTP Post JSON
【发布时间】:2014-07-24 09:46:42
【问题描述】:

我确定我在这里做错了什么。我已经按照我可以在 stackoverflow 上找到的每个示例进行操作,但仍然没有在我的环境中使用它。我很想更新我的控件和环境,但我目前被我所拥有的东西所束缚。

我正在使用:

  • 德尔福 7
  • 印地 10.0.52
  • ulkJSON.pas v1.07

我需要将此 JSON 发送到 URL:

"auth": {
    "applicationId": "appID",
    "applicationPassword": "pwd",
    "accountId": "acct",
    "userId": "dev"
}

这并没有什么特别疯狂的地方,但是当我尝试发布我的请求时,我往往会收到一条消息,即请求已正常关闭。 IDSocketHandle.pas 中的 CheckIsReadable 具有 Handleallocated = false。我不确定我在配置 IdHTTP 时做错了什么,但它就是行不通。

我已经尝试了所有这些问题的示例以及更多示例,但这些方法似乎都不适合我:

任何提示将不胜感激。

当前的变体如下所示:

procedure Tformmaintestbed.btnJSONSendClick(Sender: TObject);
var
  code: Integer;
  sResponse: string;
  JsonToSend: TStringStream;
begin
  JsonToSend := TStringStream.Create(
    '{"auth": {"applicationId": "' + edApplication.text +
    '","applicationPassword": "' + edpassword.text +
    '","accountId": "' + edaccount.text +
    '","userId": "' + edUser.text +
    '"}}');
  try
    HTTP1.Request.ContentType := 'application/json';
    HTTP1.Request.ContentEncoding := 'utf-8';

    memoRequest.lines.clear;
    memoRequest.lines.add(JsonToSend);

    try
      sResponse := HTTP1.Post(cbAddress.text, JsonToSend);
    except
      on E: Exception do
        ShowMessage('Error on request: '#13#10 + e.Message);
    end;

    memoResponse.lines.clear;
    memoresponse.lines.add(sResponse);
  finally
    JsonToSend.Free();
  end;
end;

idHTTP 组件的当前设置如下:

object HTTP1: TIdHTTP
  IOHandler = IdSSLIOHandlerSocketOpenSSL1
  AuthRetries = 0
  AuthProxyRetries = 0
  AllowCookies = True
  HandleRedirects = True
  ProxyParams.BasicAuthentication = False
  ProxyParams.ProxyPort = 0
  Request.ContentEncoding = 'utf-8'
  Request.ContentLength = -1
  Request.ContentRangeEnd = 0
  Request.ContentRangeStart = 0
  Request.ContentRangeInstanceLength = 0
  Request.ContentType = 'application/json'
  Request.Accept = 'application/json'
  Request.BasicAuthentication = False
  Request.UserAgent = 'Mozilla/3.0 (compatible; Indy Library)'
  HTTPOptions = [hoForceEncodeParams]
  Left = 564
  Top = 120
end

【问题讨论】:

  • 请求发送成功后,“just won't work”是什么意思呢?你期望发生什么?
  • 1) JSON 只是一个文本字符串:Tidhttp 应该可以正常工作,2) 您应该将 HTTP 标头中的 "content-type" 设置为“text/json”或“application/json”,3)您绝对应该使用像 WiresharkFiddler2 这样的工具来查看您的 JSON 是否正在发送,以及服务器如何(或是否)响应。
  • 请显示不适合您的实际代码。不要只是指导我们看别人的例子。显示您实际使用的代码。您可能没有将这些示例正确地整合到您的项目中。
  • 我将内容类型设置为与帖子中列出的示例相匹配。将有一条响应 JSON 消息,我可以对其进行解析以获取令牌。然后,该令牌可用于对该站点进行其他调用。随着 Fiddler 的运行,没有消息显示给我。看起来我什至没有收到消息。
  • 如果您需要有关不起作用的代码的帮助,请务必发布不起作用的代码。当您不展示如何配置它时,也很难说出您在“配置您的 IdHTTP”方面做错了什么。如果您在此处需要帮助,则需要提供相关信息。要求我们推测可能出了什么问题是没有意义的,什么时候您可以包括您正在做的事情,我们可以尝试并专门帮助您。请edit您的问题并在那里添加信息,它可以正确格式化并且人们可以很容易地找到它。谢谢。

标签: json delphi indy


【解决方案1】:

请试试这个:

procedure TForm1.Button1Click(Sender: TObject);
    var
        s: String;
        Resp_Json: string;
        Req_Json:TStream;
begin
    s:='state=1';
    s:=s+'&kind=0';
    s:=s+'&tblid=0';
    Req_Json:=TstringStream.Create(s);
    Req_Json.Position:=0;

    try
        IdHTTP1.Request.UserAgent:='Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36';
        IdHTTP1.Request.Accept := 'application/json, text/javascript, */*; q=0.01';
        IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded; charset=UTF-8';
        IdHTTP1.Request.CharSet:='utf-8';
        Resp_Json:=IdHTTP1.Post('http://[your URL]', Req_Json);
    finally
        Req_Json.Free;
    end;

    memo1.Lines.Add(IdHTTP1.ResponseText);
    memo1.Lines.Add(Resp_Json);
end;

【讨论】:

    【解决方案2】:

    HTTP1.Request.ContentEncoding 应改为 HTTP1.Request.CharSet。 UTF-8 是字符集编码,而不是内容编码。然后确保您的 JSON 数据在发布之前实际编码为 UTF-8。如果您使用的是 ASCII 字符,那么您显示的 TStringStream 代码就可以了。但是如果你使用的是非 ASCII 字符,你需要对它们进行编码,比如使用Utf8Encode()TIdHTTP 不编码 TStream 数据,它按原样发送。

    Procedure Tformmaintestbed.btnJSONSendClick(Sender: TObject);
    var
      Json: string;
      sResponse: string;
      JsonToSend: TStringStream;
    begin
      Json := '{"auth": {"applicationId": "' + edApplication.text +
        '","applicationPassword": "' + edpassword.text +
        '","accountId": "' + edaccount.text +
        '","userId": "' + edUser.text +
        '"}}';
    
      memoRequest.Text := Json;
    
      JsonToSend := TStringStream.Create(Utf8Encode(Json)); // D2007 and earlier only
      //in D2009 and later, use this instead:
      //JsonToSend := TStringStream.Create(Json, TEncoding.UTF8);
      try
        HTTP1.Request.ContentType := 'application/json';
        HTTP1.Request.CharSet := 'utf-8';
    
        try
          sResponse := HTTP1.Post(cbAddress.Text, JsonToSend);
        except
          on E: Exception do
            ShowMessage('Error on request: '#13#10 + e.Message);
        end;
      finally
        JsonToSend.Free;
      end;
    
      memoResponse.Text := sResponse;
    end;
    

    或者:

    Procedure Tformmaintestbed.btnJSONSendClick(Sender: TObject);
    var
      Json: string;
      sResponse: string;
      JsonToSend: TMemoryStream;
    begin
      Json := '{"auth": {"applicationId": "' + edApplication.text +
        '","applicationPassword": "' + edpassword.text +
        '","accountId": "' + edaccount.text +
        '","userId": "' + edUser.text +
        '"}}';
    
      memoRequest.Text := Json;
    
      JsonToSend := TMemoryStream.Create;
      try
        WriteStringToStream(JsonToSend, Json, enUTF8);
        JsonToSend.Position := 0;
    
        HTTP1.Request.ContentType := 'application/json';
        HTTP1.Request.CharSet := 'utf-8';
    
        try
          sResponse := HTTP1.Post(cbAddress.Text, JsonToSend);
        except
          on E: Exception do
            ShowMessage('Error on request: '#13#10 + e.Message);
        end;
      finally
        JsonToSend.Free;
      end;
    
      memoResponse.Text := sResponse;
    end;
    

    【讨论】:

    • 看来我的 Indy 版本和你的不一样。我没有 HTTP1.Request.CharSet 属性,如果我没有设置 IOHandler,那么我的会得到这个:请求错误:IOHandler 值无效
    • 10.0.52 是一个非常旧的版本。当前版本是 10.6.0。至于 IOHandler 错误,只有在您请求 HTTPS url 并且没有分配 SSL IOHandler 时才会发生这种情况。这一要求在最新版本中仍然适用。
    • CharSet 属性是在 2010 年的 10.5.7 中添加的。
    • 如果我能说服我的工作升级 Indy,你知道是否有任何版本与 Delphi 7 有问题?我在他们的开发快照页面上看到有几个版本 10.6.0 Indy 10.6.0 - XE6 RTM/ Indy 10.6.0 - XE5 RTM/ Indy 10.6.0 - XE4 RTM/ Indy 10.5.8 - XE2 RTM/ Indy 10.5.7 - XE RTM/印地 10.5.5 - RS2010 RTM/
    • 这些是标签,因此我们知道近年来每个主要的 Delphi 版本都附带了哪个 SVN 版本的 Indy。 Indy 本身仍然支持一直到 Delphi 5 的 Delphi 版本。
    猜你喜欢
    • 2012-08-23
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    相关资源
    最近更新 更多