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

别来无恙 提交于 2019-11-25 23:37:59

问题


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\"
    }
  }
]

回答1:


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

A mode: 'no-cors' request makes the response type opaque. The console-log snippet in the question clearly 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 mode: 'no-cors' is essentially to tell browsers, “Don’t let frontend JavaScript code access the response body or headers under any circumstances.”

I imagine you’re setting mode: 'no-cors' for the request because the response from http://localhost:8080/course doesn’t include the Access-Control-Allow-Origin response header or because your browser’s making an OPTIONS request to http://localhost:8080 because your request is one that triggers a CORS preflight.

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

  • configure the http://localhost:8080 server to send the Access-Control-Allow-Origin response header and to handle the OPTIONS 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)




回答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();
})



回答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});
      })
  }
}     



回答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;
});



回答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>  


来源:https://stackoverflow.com/questions/43317967/handle-response-syntaxerror-unexpected-end-of-input-when-using-mode-no-cors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!