Handle response - SyntaxError: Unexpected end of input when using mode: 'no-cors'

Chilliggo picture Chilliggo · Apr 10, 2017 · Viewed 39.4k times · Source

I tried a ReactJS fetch call to a REST-API and want to handle the response. The call works, i get a response, which i can see in Chrome Dev Tools:

function getAllCourses() {
fetch('http://localhost:8080/course', {
    method: 'POST',
    mode: 'no-cors',
    credentials: 'same-origin',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        objectClass: 'course',
        crud: '2'
    })
}).then(function (response) {
    console.log(response);
    return response.json();

}).catch(function (err) {
    console.log(err)
});
}

When i try to handle the response, i got a "SyntaxError: Unexpected end of input" at

return response.json();

The console.log looks like this:

Console.log(response)

My Response JSON looks like this, it is valid, i checked it with jsonlint:

[
  {
    "0x1": {
      "users": [],
      "lectures": [],
      "owner": "0x2",
      "title": "WWI 14 SEA",
      "description": null,
      "objectClass": "course",
      "id": "course_00001"
    },
    "0x2": {
      "username": "system",
      "lectures": [],
      "course": null,
      "solutions": [],
      "exercises": [],
      "roles": [
        "0x3",
        "0x4",
        "0x5"
      ],
      "objectClass": "user",
      "id": "user_00001"
    },
    "0x3": {
      "roleName": "ROLE_ADMIN",
      "objectClass": "role",
      "id": "role_00001"
    },
    "0x4": {
      "roleName": "ROLE_STUDENT",
      "objectClass": "role",
      "id": "role_00002"
    },
    "0x5": {
      "roleName": "ROLE_DOCENT",
      "objectClass": "role",
      "id": "role_00003"
    }
  }
]

Answer

sideshowbarker picture sideshowbarker · Apr 10, 2017

You need to remove the mode: 'no-cors' setting from your request. Setting no-cors mode is exactly the cause of the problem you’re having.

A no-cors request makes the response type opaque. The log snippet in the question shows that. And opaque means your frontend JavaScript code can’t see the response body or headers.

https://developer.mozilla.org/en-US/docs/Web/API/Request/mode explains:

no-cors — JavaScript may not access any properties of the resulting Response

So the effect of setting no-cors mode is essentially to tell browsers, “Don’t let frontend JavaScript code access the response body or headers under any circumstances.”

I imagine you’re trying no-cors because the response from http://localhost:8080/course doesn’t include the Access-Control-Allow-Origin response header or else because your request is one that triggers a CORS preflight, and so your browser’s doing an OPTIONS preflight.

But using no-cors mode is not the solution to those problems. The solution is either to: