Delphi HTTP Post JSON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24025646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:20:41  来源:igfitidea点击:

Delphi HTTP Post JSON

jsondelphiindy

提问by Jared Sherman

I am sure I'm doing something wrong here. I've followed every example I can find on stackoverflow and still haven't gotten this to work in my environment. I'd love to update my controls and environment, but I'm currently locked in with what I have.

我确定我在这里做错了什么。我已经遵循了我可以在 stackoverflow 上找到的每个示例,但仍然没有让它在我的环境中工作。我很想更新我的控件和环境,但我目前被我所拥有的锁定。

I am using:

我在用:

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

I need to send this JSON to a URL:

我需要将此 JSON 发送到 URL:

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

There isn't anything terribly crazy about this, but when I try to post my request I tend to get a message that the request was Closed Gracefully. CheckIsReadable in IDSocketHandle.pas has Handleallocated = false. I'm not sure what I've done wrong in configuring my IdHTTP, but it just won't work.

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

I have tried examples from all these questions and several more, but none of these approaches seem to work for me:

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

Any tips would be greatly appreciated.

任何提示将非常感谢。

The current variant looks like this:

当前的变体如下所示:

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;

The idHTTP component is current set like this:

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

回答by Remy Lebeau

HTTP1.Request.ContentEncodingshould be HTTP1.Request.CharSetinstead. UTF-8 is a charset encoding, not a content encoding. And then make sure your JSON data is actually encoded to UTF-8 before posting it. If you are using ASCII characters, the TStringStreamcode you showed is fine. But if you are using non-ASCII Characters, you need to encode them, such as with Utf8Encode(). TIdHTTPdoes not encode TStreamdata, it is sent as-is.

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;

Alternatively:

或者:

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;

回答by asep

Please try this:

请试试这个:

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;