41

I am trying to rewrite my ajax call to fetch:

Ajax:

  $.post({
    context: this,
    url: "/api/v1/users",
    data: { 
      user: 
        {
          email: email,
          password: password
        } 
    }
  }).done((user) => {
  }).fail((error) => {
  })

Fetch:

  fetch('/api/v1/users', {  
  method: 'POST',
  headers: {
    "Content-Type": "application/json"
  },      
    body: { 
    "user" : 
      {
        "email" : email,
        "password" : password
      } 
  }
  })
  .then(res => {  
    if (res.status !== 200) { {
        console.log("error")
      })          
    } else {
      res.json().then(data => {
        console.log(data)
      })
    }
  })

I am getting an error empty params ~ bad request from my server.

I also found this way to do it, but in this code below I am getting an error: Unexpected token.

  var payload = { 
    "user" : 
      {
        "email" : email,
        "password" : password
      } 
  };

  var data = new FormData();
  data.append( "json", JSON.stringify( payload ) );

  fetch('/api/v1/users', {  
  method: 'POST',
  headers: {
    "Content-Type": "application/json"
  },      
    body: data
  })

How can I rewrite the ajax request to fetch?

2
  • In nodeJS Express ALSO don't forget at the server-side: stackoverflow.com/questions/11625519/… app.use(express.bodyParser()); Commented Aug 27, 2024 at 11:48
  • In Django do not forget to add {{ csrf_token }} to your form, headers: { 'X-CSRFToken': document.querySelector( '[name=csrfmiddlewaretoken]').value } and decode the body: request.body.decode('utf-8') Commented Aug 27, 2024 at 11:52

9 Answers 9

76

Followed this topic on github: https://github.com/matthew-andrews/isomorphic-fetch/issues/34

The solution to my question is using the JSON.stringify function and set Content-Type header to application/json. Not pretty sure why the second attempt in my question didn't work though.

fetch('/api/v1/users', {  
    method: 'post',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({ "user": {
      "email" : email,
      "password" : password
    }}),
})

Official MDN Documentation:

var myHeaders = new Headers();
myHeaders.append('Content-Type', 'application/json');

fetch('/contact-form', {
    method: 'POST',
    headers: myHeaders,
    mode: 'cors',
    cache: 'default',
    body: JSON.stringify(fields)
}).then(() => {
    dispatch(contactFormSubmitSuccess());
});
Sign up to request clarification or add additional context in comments.

3 Comments

(it fails in chrome, instead this, i'm make encode params to url)
Adding headers as Dudis suggested worked for me, thanks!
Didn't work for me, fetch is still doing a get instead of post!
23

TL;DR Without mode: 'cors' your JSON body won't go through.

I wrestled with this for a bit. cors was the issue. Assuming you are performing a request from one domain to another (i.e. from localhost:8080 to localhost:3000) you need to have mode: 'cors' in the fetch settings & your receiving domain (localhost:3000) needs to allow requests from the sending domain (localhost:8080).

So the above description in code:

request from localhost:8080 to localhost:3000

fetch('http://localhost:3000/users/sign_in', {
      method: 'POST',
      mode: 'cors', // this cannot be 'no-cors'
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "user": {
          "email": `${this.state.userEmail}`,
          "password": `${this.state.userPass}`
        }
      }),
    })

And then make sure your receiving domain localhost:3000 allows CORS from localhost:8080.

Comments

15
headers: {'Content-Type': 'application/json'}

already answered

4 Comments

yeah, can not stress the header enough. I spent way too long confused, when the issue was me misspelling application in the header. First step is to check for typos.
That literally happened to me too with the exact same fetch functionality. Can stress what Jacob C. said enough. Typos people!
for me it was 'header: {'Content-Type': 'application/json'}'. bloody typos
without an s, it just cost you another day. :(
10

Worked in this way when sending body as json failed.

        var formData = new FormData();
        formData.append('key1', 'value1');
        formData.append('key1', 'value2');

        fetch('url', {
            method: 'post',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'multipart/form-data'
            },
            body: formData
        }`)`

In my case, the server only identified the content through the form-data submission. The code was not written to read the request body as json. So there is a possibility to have an issue with your server side code as well.

1 Comment

after lot of struggle the above method worked for me. thanks for the explanation.
8

If you're using an Express server to handle the requests, make sure you add in this line:

app.use(express.json({limit:'1mb'}))

Comments

7

The only thing working for me was to put

app.use(express.json())

in my main server file.

Comments

2

You should try this:

fetch('/api/v1/users', {
    method: 'post',
    body: JSON.stringify({"user":{
        "email": email,
        "password": password
    }}),
});

fetch API

1 Comment

Thanks, it's basically the same like my second example in my question. It's still showing me params missing although the ajax version works just fine.
1

Try putting (body-parser) at the top of your app.js / server.js :

app.use(bodyParser.json());

Comments

-1

The problem is that fetch does not work with no-cors. So you should set mode on cors like this:

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");

const Params = {
  key: value,  // replace this by your data key and value
};

await fetch( "url_here",
  {
    method: "POST",
    headers: myHeaders,
    mode: "cors",
    cache: "default",
    body: JSON.stringify(Params),
 }
).then((response) => response.json())
  .then((data) =>
    console.log(data)
  )
  .catch((error) => console.log(error));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.