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:
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" } } ]
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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. 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 resultingResponse
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 does an OPTIONS
preflight.
But using no-cors
mode is not the solution to those problems. The solution is either to:
-
configure the
http://localhost:8080
server to send theAccess-Control-Allow-Origin
response header and to handle theOPTIONS
request - or set up a CORS proxy using code from https://github.com/Rob–W/cors-anywhere/ or such (see the How to use a CORS proxy to get around “No Access-Control-Allow-Origin header” problems section of the answer at No ‘Access-Control-Allow-Origin’ header is present on the requested resource—when trying to get data from a REST API)
Method 2
In your then
you should check if the response is OK before returning response.json
:
.then(function (response) { if (!response.ok) { return Promise.reject('some reason'); } return response.json(); })
If you want to have the error message in your rejected promise, you can do something like:
.then(function (response) { if (!response.ok) { return response.text().then(result => Promise.reject(new Error(result))); } return response.json(); })
Method 3
I know this answer might be super late and might have been resolved but i just had the same issue today and I just needed to add a ‘,’ at the end of the headers hash and i stopped getting the error
export function addContacts(formData) { return(dispatch) => { dispatch({type: 'POSTING_CONTACTS'}); console.log(formData) return fetch(uri, { method: 'POST', body: JSON.stringify({contact: {name: formData.name, phone_number: formData.phoneNumber}}), headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, }) .then(response => { return response.json() }).then(responseJSON => { console.log(responseJSON) return dispatch({type: 'ADD_CONTACT', payload: responseJSON}); }) } }
Method 4
You can avoid the problem with CORS policy by adding in the header of php or another server endpoint the row:
<?php header('Access-Control-Allow-Origin: *'); //or header('Access-Control-Allow-Origin: http://example.com'); // Reading JSON POST using PHP $json = file_get_contents('php://input'); $jsonObj = json_decode($json); // Use $jsonObj print_r($jsonObj->message); ... // End php ?>
Model of working fetch code with POST request is:
const data = { optPost: 'myAPI', message: 'We make a research of fetch' }; const endpoint = 'http://example.com/php/phpGetPost.php'; fetch(endpoint, { method: 'POST', body: JSON.stringify(data) }) .then((resp) => resp.json()) .then(function(response) { console.info('fetch()', response); return response; });
Method 5
Simply copy the following code and paste it on your web.config file under <system.webServer>
tag.
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /> </customHeaders> </httpProtocol>
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0