【问题标题】:How to send data in request body with a GET when using jQuery $.ajax()使用 jQuery $.ajax() 时如何使用 GET 在请求正文中发送数据
【发布时间】:2012-04-24 13:29:38
【问题描述】:

我正在使用的服务 API 有一个给定的 GET 方法,该方法需要在请求正文中发送数据。

正文中所需的数据是由连字符分隔的 id 列表,可能非常大,因此必须在正文中发送,否则它可能会在浏览器/代理/网络服务器等链中的某处出现 foobar。请注意,我无法控制服务或 API,因此请不要提出更改建议。

我正在使用以下 jQuery 代码,但是观察提琴手中的请求/响应,我可以看到我发送的“数据”总是被转换并附加到查询字符串中,尽管我将“processData”选项设置为 false。 .

$.ajax({
   url: "htttp://api.com/entity/list($body)",
   type: "GET",
   data: "id1-id2-id3",
   contentType: "text/plain",
   dataType: "json",
   processData: false, // avoid the data being parsed to query string params
   success: onSuccess,
   error: onError
});

有谁知道我可以如何强制在请求正文中发送“数据”值? 感谢您提供任何帮助,在此先感谢。

【问题讨论】:

  • “在体内”?我能想到的唯一一件事就是 remotely 接近你所要求的是一个 POST 请求......(POST /path HTTP/1.0\r\n<headers>\r\n\r\n<post_vars>
  • 如果 API 是通用的,并且遵守 HTTP 规范,我认为它不会接受在 GET 请求正文中发送的参数,即使您设法做到了。您确定吗?有用的帖子stackoverflow.com/questions/978061/http-get-with-request-body
  • 基本上这是不可能的,因为正如人们所说的那样,它不是 HTTP 规范的一部分。最后,我们不得不将 id 放在查询字符串上并翻阅结果,这样它就不会太长。我会接受给出的答案,谢谢 EndangerredMassa。
  • 虽然不是标准的,但在某些情况下这很有用。发送 utf-8 编码的 GET 正文时,或传递大型 json 正文时。 Elastic Search 广泛使用这种风格。
  • 发送 GET 正文是否不如发送 POST 正文安全?

标签: javascript jquery ajax


【解决方案1】:

一般来说,系统不是这样使用 GET 请求的。因此,很难让您的库配合使用。事实上,spec 表示“如果请求方法是区分大小写的 GET 或 HEAD 匹配,则将其视为数据为空。”所以,我认为除非你使用的浏览器不遵守规范的那部分,否则你很不走运。

您可能可以在自己的服务器上为 POST ajax 请求设置一个端点,然后在您的服务器代码中将其重定向到带有正文的 GET 请求。

如果您不完全依赖以正文作为数据的 GET 请求,那么您有两种选择。

POST 与数据:这可能是你想要的。如果您正在传递数据,那可能意味着您正在修改某些模型或在服务器上执行某些操作。这些类型的操作通常通过 POST 请求完成。

使用查询字符串数据获取:您可以将数据转换为查询字符串参数,然后将它们传递给服务器。

url: 'somesite.com/models/thing?ids=1,2,3'

【讨论】:

  • 虽然我很感谢您的意见,但这两项建议都涉及更改我所说的不可能的服务。
  • 感谢您添加将 POST 转换为带有正文的 GET 的代理的额外建议。我试图在 .NET 中实现这一点,但它引发了一个“ProtocolViolationException”异常,并出现错误“无法使用此动词发送内容主体”,这清楚地重新强调了带有主体的 GET 不是支持用例。
  • Elasticsearch 广泛使用 GET 和 body
  • @EndangeredMassa,“如果您正在传递数据,那可能意味着您正在修改某些模型或在服务器上执行某些操作。这些类型的操作通常通过 POST 请求完成。”在一般情况下是不正确的。该请求还可以是一个搜索查询,其中没有修改任何模型,并且服务器正在使用请求中提供的参数执行查找。这些查询请求通常是普通的 GET 请求,例如在 google.com/search?q=REST,HTTP,GET,query 中。
  • “可能意味着您正在修改某些模型或在服务器上执行某些操作。” ——可能,但并非总是如此。我有一个批处理的 GET 请求。如果我在查询中全部发送它太长了。我唯一的选择是更改服务器配置或假装这是 POST 请求的适当情况。抱怨。
【解决方案2】:

我们一般都知道,按照http标准发送数据,我们一般使用POST请求。 但是如果你真的想使用 Get 在你的场景中发送数据 我建议您使用查询字符串或查询参数。

1.GET使用Query字符串作为{{url}}admin/recordings/some_id

这里 some_id 是 mendatory 参数发送并且可以使用和 req.params.some_id 在服务器端。

2.GET使用查询字符串为{{url}}admin/recordings?durationExact=34&isFavourite=true

这里的 durationExact ,isFavourite 是 可选 要发送的字符串,可以使用 req.query.durationExactreq.query.isFavourite在服务器端。

3.GET 发送数组 {{url}}admin/recordings/sessions/?os["Windows","Linux","Macintosh"]

你可以像这样在服务器端访问这些数组值

let osValues = JSON.parse(req.query.os);
        if(osValues.length > 0)
        {
            for (let i=0; i<osValues.length; i++)
            {
                console.log(osValues[i])
                //do whatever you want to do here
            }
        }

【讨论】:

    【解决方案3】:

    以防万一有人仍然提出这个问题:

    任何请求中都有一个body查询对象。不需要自己解析。

    例如如果你想使用 GET 从客户端发送 accessToken,你可以这样做:

    const request = require('superagent');
    
    request.get(`http://localhost:3000/download?accessToken=${accessToken}`).end((err, res) => {
      if (err) throw new Error(err);
      console.log(res);
    });

    然后服务器请求对象看起来像{request: { ... query: { accessToken: abcfed } ... } }

    【讨论】:

    • OP 要求的是request.body,而不是request.query。您提到了POST,但您仍然在代码示例中使用request.get()
    • 是的,我明白了。但是查询和正文都可以使用得到相同的结果。我认为他很容易考虑 request.query 作为替代方案。
    • 用户可以在浏览器的地址栏中看到request.query。有时我们想向用户隐藏我们传输的数据。所以,我们还是更喜欢 POST 请求
    猜你喜欢
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2015-12-07
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多