Fetch post with body data not working params empty
Asked Answered
E

9

37

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?

Elephantiasis answered 3/10, 2016 at 23:34 Comment(0)
E
71

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());
});
Elephantiasis answered 4/10, 2016 at 13:6 Comment(3)
(it fails in chrome, instead this, i'm make encode params to url)Khudari
Adding headers as Dudis suggested worked for me, thanks!Decease
Didn't work for me, fetch is still doing a get instead of post!Prurient
Z
22

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.

Zooid answered 19/1, 2021 at 22:32 Comment(0)
H
15
headers: {'Content-Type': 'application/json'}

already answered

Heine answered 8/6, 2019 at 15:54 Comment(4)
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.Frederico
That literally happened to me too with the exact same fetch functionality. Can stress what Jacob C. said enough. Typos people!Marron
for me it was 'header: {'Content-Type': 'application/json'}'. bloody typosMediocre
without an s, it just cost you another day. :(Coggins
A
9

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.

Astral answered 15/8, 2018 at 7:53 Comment(1)
after lot of struggle the above method worked for me. thanks for the explanation.Meilhac
T
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'}))
Tchao answered 22/6, 2020 at 10:31 Comment(0)
D
6

The only thing working for me was to put

app.use(express.json())

in my main server file.

Delayedaction answered 30/12, 2021 at 16:30 Comment(0)
F
2

You should try this:

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

fetch API

Foskett answered 4/10, 2016 at 0:16 Comment(1)
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.Elephantiasis
C
1

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

app.use(bodyParser.json());
Crass answered 16/12, 2021 at 19:46 Comment(0)
Z
0

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));
Zipah answered 24/11, 2023 at 2:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.