IdHttp : 如何处理 json 请求和响应

IdHttp : how to deal with json request and response

我遇到过一些使用 JSON 进行请求和响应的站点
我遇到两种类型:
1- application/x-www-form-urlencoded 作为请求和 return 响应 application/json 内容类型
2- application/json 请求和响应的内容类型
type 1 中,我尝试使用
更改响应内容类型 mIdHttp.Response.ContentType := 'application/json';
但是使用 http 分析器我可以看到它没有改变并且仍然是 text/html
现在我不知道问题是否在于我无法更改内容类型,但我不知道如何处理 json !
关于 json 的几个问题:
1- 在 posting 时我是否必须对 json 数据进行编码?怎么样?
2- 我如何解析 json 响应代码?如何得到它?它需要某种编码或特殊转换吗?
3- json 的哪种 idhttp 设置随每个站点而变化并需要配置?

我知道我的问题听起来有点笼统,但所有其他问题都非常具体,在处理 'application/json' 内容类型时没有解释基础知识。

编辑 1 :
感谢 Remy Lebeau 的回答,我能够成功地使用 type 1
但我仍然无法发送 JSON 请求,有人可以分享一个工作示例吗,这是 posting 信息的网站之一,请使用这个作为您的示例:

一个重要提示:这个特定站点的post和请求内容完全一样!这让我感到困惑,因为在网站上,我指定了一个 start date 和一个 end date 然后单击 folder like icon 并发送了这个 post (你可以在上面看到的那个) ,并且 result 应该是 links (而且它是) 但是 而不是只出现在 request content 它们也出现在 post ! (我也在尝试获取链接,但是在 post 链接,我想要的东西,也被发送了,我怎么能 post 我没有的东西!!?)

为了更清楚起见这是我填写日期和提到的图标的地方:

您不能指定响应的格式,除非所请求的资源提供明确的输入参数或专门用于该确切目的的 URL(即请求以 html 形式发送响应, xml、json 等)。设置 TIdHTTP.Response.ContentType 属性 是没有用的。它将被响应的实际 Content-Type header 覆盖。

要在请求中发送 JSON,您必须post将其作为TStream,如TMemoryStreamTStringStream,根据需要设置TIdHTTP.Request.ContentType,例如:

var
  ReqJson: TStringStream;
begin
  ReqJson := TStringStream.Create('json content here', TEncoding.UTF8);
  try
    IdHTTP1.Request.ContentType := 'application/json';
    IdHTTP1.Post(URL, ReqJson);
  finally
    ReqJson.Free;
  end;
end;

收到JSON,TIdHTTP可以

  1. return 它作为 String(使用 server-reported 字符集解码):

    var
      ReqJson: TStringStream;
      RespJson: String;
    begin
      ReqJson := TStringStream.Create('json content here', TEncoding.UTF8);
      try
        IdHTTP1.Request.ContentType := 'application/json';
        RespJson := IdHTTP1.Post(URL, ReqJson);
      finally
        ReqJson.Free;
      end;
      // use RespJson as needed...
    end;
    
  2. 将原始字节写入您选择的输出 TStream

    var
      ReqJson: TStringStream;
      RespJson: TMemoryStream;
    begin
      RespJson := TMemoryStream.Create;
      try
        ReqJson := TStringStream.Create('json content here', TEncoding.UTF8);
        try
          IdHTTP1.Request.ContentType := 'application/json';
          RespJson := IdHTTP1.Post(URL, ReqJson, RespJson);
        finally
          ReqJson.Free;
        end;
        RespJson.Position := 0;
        // use RespJson as needed...
      finally
        RespJson.Free;
      end;
    end;
    

HTTP 响应代码在 TIdHTTP.Response.ResponseCode(和 TIdHTTP.ResponseCode)属性.

中可用