将jquery ajax POST请求更改为fetch api POST

时间:2017-06-08 07:20:23

标签: javascript ajax fetch-api

我有一些json数据,我使用$ .ajax发布到API,但我想更新它以使用fetch API。但是我似乎设置了Fetch API请求最终返回403所以我必须丢失一些东西,但我无法解决它。

Ajax请求:

$.ajax({
        type: 'POST',
        url: url,
        data: {
            'title': data.title,
            'body': data.body,
            'csrfmiddlewaretoken': csrf_token,
            'request_json': true
        },
        success: function (data) {
            console.log(data)
        }
    });

获取尝试(许多中的一个):

let payload = {
    'title': data.title,
    'body': data.body,
    'csrfmiddlewaretoken': csrf_token,
    'request_json': true
}

let request = new Request(url, {
    method: 'post',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body:  JSON.stringify( payload )
});

fetch(request)
        .then((response) => {
            if (!response.ok) {
                throw Error(response.statusText);
            }
            return response;
        })
        .then((response) => response.json())

我尝试过各种不同的标题,内容编码以及使用以下方式将数据作为表单数据发送:

let form_data = new FormData();
form_data.append( "json", JSON.stringify( payload ) );

let request = new Request(url, {
    method: 'post',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body:  form_data
});
...

任何帮助都会很棒,如果您需要更多信息,请告诉我

由于

2 个答案:

答案 0 :(得分:2)

要将现有的jQuery.ajax请求移植到fetch,您需要考虑jQuery总是包含cookie,但fetch没有。

Quoting MDN(强调我的):

  

请注意,fetch规范与jQuery.ajax()的不同之处主要有两种方法:    - 从fetch()返回的Promise不会拒绝HTTP错误状态[...]
   - 默认情况下,如果网站依赖于维护用户会话(发送Cookie,凭据标头)必须发送。

编辑:规格从那时起发生了变化,所以这应该不再是一个问题:

  

自2017年8月25日起。规范将默认凭据策略更改为同源。 Firefox自61.0b13以来发生了变化

所以以下(回到原始答案)仅适用于"年龄较大的"浏览器。

感谢大卫里士满的评论:)

所以你得到403 (Forbidden),因为你的API可能依赖于cookie来进行身份验证/授权(即使在你发送csrfmiddlewaretoken的情况下,服务器端框架可能仍然期望使用cookie - 猜猜Django?)。

要解决此问题,add credentials: "same-origin" to your Request(*),如下:

let request = new Request(url, {
    method: 'post',
    credentials: 'same-origin',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
});

(*)credentials的有效选项为:

  • omit:永远不要发送Cookie。这是默认设置(和您的问题)。
  • same-origin:如果网址与调用脚本位于同一源,则仅发送Cookie。
  • include:始终发送Cookie,即使是跨域通话。

答案 1 :(得分:0)

你说:

'Content-Type': 'application/x-www-form-urlencoded'

 body:  JSON.stringify( payload )

JSON编码与WWW表格编码不同!

你也试过

form_data.append( "json", JSON.stringify( payload ) );

FormData对象将转换为Multipart MIME。

Multipart MIME也与WWW表格编码数据不同。

JSON嵌套在Multipart MIME中甚至更少。

This question描述了如何将对象(payload)转换为表单编码字符串。