[javascript] fetch gives an empty response body

I have a react/redux application and I'm trying to do a simple GET request to a sever:

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
}).then((response) => {
  console.log(response.body); // null
  return dispatch({
    type: "GET_CALL",
    response: response
  });
})
.catch(error => { console.log('request failed', error); });

The problem is that the response body is empty in the .then() function and I'm not sure why. I checked examples online and it looks like my code should work so I'm obviously missing something here. The thing is, if I check the network tab in Chrome's dev tools, the request is made and I receive the data I'm looking for.

Can anybody shine a light on this one?

EDIT:

I tried converting the reponse.

using .text():

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
})
.then(response => response.text())
.then((response) => {
  console.log(response); // returns empty string
  return dispatch({
    type: "GET_CALL",
    response: response
  });
})
.catch(error => { console.log('request failed', error); });

and with .json():

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
})
.then(response => response.json())
.then((response) => {
  console.log(response.body);
  return dispatch({
    type: "GET_CALL",
    response: response.body
  });
})
.catch(error => { console.log('request failed', error); }); // Syntax error: unexpected end of input

Looking in the chrome dev tools:

enter image description here

This question is related to javascript fetch-api

The answer is


Try to use response.json():

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
}).then((response) => {
  console.log(response.json()); // null
  return dispatch({
    type: "GET_CALL",
    response: response.json()
  });
})
.catch(error => { console.log('request failed', error); });

You will need to convert your response to json before you can access response.body

From the docs

fetch(url)
  .then(response => response.json())
  .then(json => {
    console.log('parsed json', json) // access json.body here
  })

In many case you will need to add the bodyParser module in your express node app. Then in your app.use part below app.use(express.static('www')); add these 2 lines app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json());


fetch("http://localhost:8988/api", {
        //mode: "no-cors",
        method: "GET",
        headers: {
            "Accept": "application/json"
        }
    })
    .then(response => {
        return response.json();
    })
    .then(data => {
        return data;
    })
    .catch(error => {
        return error;
    });

This works for me.


fetch("http://localhost:8988/api", {
    method: "GET",
    headers: {
       "Content-Type": "application/json"
    }
})
.then((response) =>response.json());
.then((data) => {
    console.log(data);
})
.catch(error => {
    return error;
});

You must read the response's body:

fetch(url)
  .then(res => res.text()) // Read the body as a string

fetch(url)
  .then(res => res.json()) // Read the body as JSON payload

Once you've read the body you will be able to manipulate it:

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
})
  .then(response => response.json())
  .then(response => {
    return dispatch({
      type: "GET_CALL",
      response: response
    });
  })

This requires changes to the frontend JS and the headers sent from the backend.

Frontend

Remove "mode":"no-cors" in the fetch options.

fetch(
  "http://example.com/api/docs", 
  {
    // mode: "no-cors",
    method: "GET"
  }
)
  .then(response => response.text())
  .then(data => console.log(data))

Backend

When your server responds to the request, include the CORS headers specifying the origin from where the request is coming. If you don't care about the origin, specify the * wildcard.

The raw response should include a header like this.

Access-Control-Allow-Origin: *