最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Change a jquery ajax POST request into a fetch api POST - Stack Overflow

programmeradmin2浏览0评论

I have some json data that I have been posting to an API using $.ajax but I would like to update this to use the fetch API. However I seem to have it setup the Fetch API request ends up returning a 403 so I must be missing something but I can't work it out.

Ajax request:

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

Fetch attempt (one of many):

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())

I have tried with various different headers, content encoding and sending the data as form data using:

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
});
...

Any help would be great and if you need any more info let me know

Thanks

I have some json data that I have been posting to an API using $.ajax but I would like to update this to use the fetch API. However I seem to have it setup the Fetch API request ends up returning a 403 so I must be missing something but I can't work it out.

Ajax request:

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

Fetch attempt (one of many):

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())

I have tried with various different headers, content encoding and sending the data as form data using:

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
});
...

Any help would be great and if you need any more info let me know

Thanks

Share Improve this question edited Jun 11, 2017 at 18:55 Hugues M. 20.5k6 gold badges42 silver badges66 bronze badges asked Jun 8, 2017 at 7:20 Designer023Designer023 2,0122 gold badges27 silver badges45 bronze badges 3
  • Why not headers: headers: { 'Content-Type': 'application/json' }? – sideshowbarker Commented Jun 8, 2017 at 11:17
  • I tried this but it didn't seem to work. I will give it a go again, perhaps something else was messing it up! – Designer023 Commented Jun 9, 2017 at 10:46
  • @sideshowbarker — The working (jQuery) code uses www form encoding. There's nothing to suggest the server supports a JSON formatted request. – Quentin Commented Jun 12, 2017 at 11:55
Add a ment  | 

2 Answers 2

Reset to default 3

To port an existing jQuery.ajax request to fetch, you need to consider that jQuery always includes cookies for you, but fetch does not.

Quoting MDN (emphasis mine):

Note that the fetch specification differs from jQuery.ajax() in mainly two ways that bear keeping in mind:
- The Promise returned from fetch() won’t reject on HTTP error status [ ... ]
- By default, fetch won't send or receive any cookies from the server, resulting in unauthenticated requests if the site relies on maintaining a user session (to send cookies, the credentials header must be sent).


Edit: spec has changed since then, so this should no longer be a problem:

Since Aug 25, 2017. The spec changed the default credentials policy to same-origin. Firefox changed since 61.0b13.

So the following (returning to original answer) only applies to "older" browsers.

Thanks David Richmond from ments :)


So you get 403 (Forbidden) because your API likely relies on cookies for authentication/authorization (even in your case, where you send a csrfmiddlewaretoken, the server-side framework might still expect a cookie with that -- guessing Django?).

To fix this, add credentials: "same-origin" to your Request (*), like so:

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

(*) Valid options for credentials are:

  • omit: Never send cookies. This is the default (and your problem).
  • same-origin: Only send cookies if the URL is on the same origin as the calling script.
  • include: Always send cookies, even for cross-origin calls.

You say:

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

and

 body:  JSON.stringify( payload )

JSON Encoding is not the same thing as WWW Form Encoding!


You also tried

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

FormData objects are converted to Multipart MIME.

Multipart MIME is also not the same as WWW Form Encoded data.

JSON nested inside Multipart MIME even less so.


This question describes how to convert an object (payload) into a Form Encoded string.

发布评论

评论列表(0)

  1. 暂无评论