在 JavaScript 中发送带有正文的 GET 请求 (XMLHttpRequest)

And*_*vin 18 javascript ajax rest xmlhttprequest http-get

我必须与从 GET 请求正文中获取参数的 API 进行交互。我知道这可能不是最好的主意,但它是 API 的构建方式。

当我尝试使用 构建查询时XMLHttpRequest,看起来负载根本没有发送。您可以运行它并查看网络选项卡;请求已发送,但没有正文(在最新的 Chrome 和 Firefox 中测试):

const data = {
  foo: {
    bar: [1, 2, 3]
  }
}
const xhr = new XMLHttpRequest()
xhr.open('GET', 'https://my-json-server.typicode.com/typicode/demo/posts')
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
xhr.send(JSON.stringify(data))
Run Code Online (Sandbox Code Playgroud)

诸如 axios 之类的库是基于 XMLHttpRequest 构建的,因此它们也无法正常工作...

有没有办法在 JavaScript 中实现这一点?

Iva*_*var 22

不,不可能在 JavaScript 中发送带有正文的 GET 请求。

看起来负载根本没有发送

那是正确的。这在规范中定义:

send(body)方法必须运行以下步骤:

...

  1. 如果请求方法是GETHEAD,则将body设置为 null。

此外,通过Fetch API的请求不允许使用正文。从规范

  1. 如果 init["body"] 存在且非空或 inputBody 非空,并且请求的方法是GETor HEAD,则抛出 TypeError 。

最好是 API 可以修复。

如果这是不可能的,您可以添加一个服务器端脚本,您可以将其用作将请求传递给 API 的代理。您可以使用带有 URL 中的数据而不是正文的 GET 请求调用此脚本,或者使用带有正文的 POST 请求。然后,此脚本可以使用主体发出 GET 请求(只要所选语言支持它)。

  • 不是为了激怒 HTTP 诸神,但郑重​​声明,在 2019 年,这个规范似乎很愚蠢。我经常发现自己想要随请求一起发送一些有效负载。有效负载可能非常大,因此我不希望它出现在 URL 中。从语义上讲,我正在执行 GET 请求(“给我一些东西。这是我想要的详细信息。不要创建任何东西。”),并且此规范要求我将其设为 POST/PUT 请求或使用其他一些黑客技术。 (19认同)
  • @JohnCarrell HTTP 规范实际上并不禁止它:“GET 请求消息中的有效负载没有定义的语义;在 GET 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。” https://tools.ietf.org/html/rfc7231#section-4.3.1 (3认同)
  • 我认为这些框架十多年来已经被打破。休息 > HTTP。如果我想表示我想在给定某些参数的情况下获取一些数据,并且由于序列化简单性、大小、字符集、安全性或任何其他原因,这些参数不适合查询字符串,那么我应该能够传递这些参数带有 Body 的参数到“GET”端点。通过调用“PUT”或“POST”来请求数据(即使基于参数)是不完全正确的。(并不是说您不能期望它们在各自的添加/更新操作之后返回数据)。 (2认同)
  • “如果 API 能够被修复那就最好了。” - API 没有被破坏。使用它的框架是。 (2认同)