Last updated: Mar 7, 2024
Reading time·4 min
mode
is not set to no-cors
when making the request.json()
method on the responseThe issue where fetch()
returns an empty response body when making an HTTP
request occurs for multiple reasons:
mode
to no-cors
when making the HTTP request (this returns an
opaque response)..json()
method on the response to get the resolved
body.mode
is not set to no-cors
when making the requestThe first thing you should check is that mode
is not set to node-cors
when
issuing the fetch
request.
async function getUser() { try { const response = await fetch('https://randomuser.me/api/', { // 👇️ remove this // mode: 'no-cors', // 👈️ method: 'GET', headers: { Accept: 'application/json', }, }); if (!response.ok) { throw new Error(`Error! status: ${response.status}`); } const result = await response.json(); return result; } catch (err) { console.log(err); } } getUser().then(data => { console.log(data); });
When mode is set to no-cors, an opaque response is returned from the server.
This means that your JavaScript code will not be able to access any properties of the resulting response.
mode: 'no-cors'
line if you've set it when making the HTTP request.CORS is a mechanism that allows a server to use a combination of HTTP headers to indicate from which domains, other than its own, it receives requests.
If your server doesn't send back HTTP headers that allow your browser to access it, you will get an empty response body.
In short, you can try to set the Access-Control-Allow-Origin
header to an
asterisk "*"
to indicate that all domains can access your server.
Access-Control-Allow-Origin: *
If your server sends back this header with a value of an asterisk, then all domains will be able to access it.
However, this is a quick and dirty solution and might not work especially if you
send requests that require authentication (through Cookies or an Authorization
header).
I have written a detailed article on how to configure CORS correctly to be able to make fetch requests.
Click on the link and follow the instructions if you need to configure CORS on your server to enable your browser to make HTTP requests.
.json()
method on the responseAnother common cause of the error is when you forget to wait for the Promise to resolve.
When you make a fetch request, you have to call the .json() method on the response to be able to access the response body.
response.json()
method returns a Promise that resolves with the response data, so you have to await the promise.Here is an example.
async function getUser() { try { // 1) await the fetch() request to get the response const response = await fetch('https://randomuser.me/api/', { method: 'GET', headers: { Accept: 'application/json', }, }); if (!response.ok) { throw new Error(`Error! status: ${response.status}`); } // 2) await the .json() call to get the data const result = await response.json(); return result; } catch (err) { console.log(err); } } // 3) use the .then() syntax to await the Promise // that the async function returns getUser().then(data => { console.log(data); });
Notice that I called the .json()
method on the response and awaited the
Promise
The result
variable stores the data that was returned from the server.
All async functions return a
Promise object, so I had to call the .then()
method when calling the
getUser()
function.
The function I passed to .then()
gets called with the response data.
The example above uses the async/await
syntax but you can also use .then()
exclusively.
function getUser() { // 1) return the Promise return fetch('https://randomuser.me/api/', { method: 'GET', headers: { Accept: 'application/json', }, }) .then(response => { if (!response.ok) { throw new Error(`Error! status: ${response.status}`); } // 2) return the call to .json() return response.json(); }) .catch(error => { console.log('error: ', error); }); } // 3) call .then() on the Promise to resolve it getUser().then(data => { console.log(data); });
We returned the call to the fetch()
function from the getUser()
function.
Notice that we also returned the call to the .json()
method from the callback
function we passed to .then()
.
The last step is to call the .then()
method on the Promise we got from calling
getUser()
to wait for it to resolve with the data.
If I run the code sample, I can see that the response body gets logged to the console.
The .then()
method always returns a Promise, so you can chain as many
.then()
calls as necessary.
The callback function you pass to .then()
gets called with the value you
returned from the previous .then()
call.
somePromise.then(value => { return value }).then(value => { // same value that was returned from the previous .then() callback console.log(value) })
I have written a couple of articles that go more in-depth on how to make HTTP requests:
If you run into issues when trying to configure CORS on your server, check out the following article.
To resolve the issue where fetch()
returns an empty response body when
making an HTTP request, make sure:
mode
to no-cors
when making the HTTP request..json()
method on the response you get from the server.