http - 如何使用 TIdHttp GET 请求发送内容?

标签 http delphi indy idhttp

我正在尝试访问一个 REST 服务器,该服务器的端点使用 GET 动词,同时它还需要在正文中发送 json 数据

我正在尝试使用 Get 方法通过 TIdHttp 类来实现这一点。

现在我用 json 数据创建一个 TStringStream,然后将该流分配给 TIdHttp 对象的 Request.Source 属性。

然而,服务器以错误代码响应,表明它没有收到正文。

如何使用 TIdHttp 发送带有 GET 请求的正文?

最佳答案

正如 Remy 所建议的,您可以破解“访问器”类,以设法通过类型强制调用来访问此方法。

或者,您可以简单地将 TIdHttp 子类化并添加一个合适的、新的 Get() 便捷方法,遵循为所有其他此类方法。

例如像这样的东西:

interface

  type
    TOurHttp = class(TIdHttp)
    public
      procedure Get(aUrl: String; aRequestBody, aResponseContent: TStream);
    end;

implementation

  procedure TOurHttp.Get(aUrl: String; aRequestBody, aResponseContent: TStream);
  begin
    DoRequest(Id_HttpMethodGet, aUrl, aRequestBody, aResponseContent, []);
  end;

这就是我们在我之前工作的一家公司所做的,构建集成/中间件软件,因为有许多示例提供的 Indy 便利方法(当时)没有涵盖我们所有的用例,而不仅仅是 GET ,尤其是涉及到 REST Api 时。请注意,以上不是我们当时的实际代码,我无法再访问它。

我们没有直接使用 TIdHttp 类,而是使用了 TOurHttp(不是真实名称),它被赋予了许多对我们有用的额外便利方法。我们还发现我们必须对其他方面进行更改和扩展,例如 IgnoreReplies 行为,以适应各种“流氓”REST Api 服务器行为(并非所有行为都符合 HTTP 标准),这又一次您不会在大多数用例中找到。

当然,您可以尝试要求 Api 或 HTTP 服务器的提供商更改他们的端,而不是修复您的客户端行为。祝你好运。 ;)

背景阅读

HTTP 协议(protocol)规范确实允许 GET 请求提交请求主体,但绝大多数实现都不允许(或干脆忽略任何此类内容)。这可能是因为历史上绝大多数实现都以浏览器行为为目标或由浏览器行为驱动,再加上不幸的是 HTTP 规范在该领域允许一些“回旋余地”。

这导致了我们今天所处的位置,在撰写本文时(2019 年 1 月)HTTP 规范的相关部分 RFC7231 has this to say about content in a GET request :

A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.

即请求内容是允许的,因为它没有被明确禁止并且它的使用被认为是可能的并且有时是预期的(并且只是有时被拒绝)。但是您不能指望服务器对此类请求采用任何特定解释(甚至接受)。

这当然无助于客户端处理已经决定其特定解释的特定服务器。通过以这种方式向错误的做法让步,HTTP 规范的这种迭代就没有多大用处了;它只是简单地描述了实践中的差异,而不是提供可以测试实现的合规性/准确性的规范。

关于http - 如何使用 TIdHttp GET 请求发送内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54330196/

相关文章:

java - 如何让 HttpServer 并行创建多个 HttpHandlers?

delphi - Delphi-针对另一个文件检查文件的每一行

delphi - Firebird TIBQuery 插入并返回 ... INTO

android - 如何使用 Indy HTTP Get 命令正确终止线程?

android - 如果 Android 中的 HttpGet 操作持续时间过长,如何避免出现错误 10053 (WSAECONNABORTED)?

file - 在 Go 中写入文件中的字节范围

function - 在 golang 中,使用 net/http 时如何调用带和不带尾随括号的函数

security - 是什么导致 "this connection is untrusted"问题?

delphi - 从Windows控制台启动一个GUI程序,然后将其设置为 'detach'

delphi - 如何在 Delphi 7 中通过 SSL 和 Indy 发送电子邮件