fetch() unexpected end of input

JavascriptJsonCorsFetch Api

Javascript Problem Overview


I am using fetch() to grab data from api server. My error looks like this:

Uncaught (in promise) SyntaxError: Unexpected end of input at 
  fetch.then.blob.

Can you please tell me what am I doing wrong.

const weatherAPi ='https://www.metaweather.com/api/location/523920';
fetch(weatherAPi, {
  mode: 'no-cors'
}).then(blob => blob.json())
  .then(data => console.log(data))

Javascript Solutions


Solution 1 - Javascript

Opaque Responses

A response for a no-cors request to a cross-origin resource has a response type of 'opaque'. If you log the response before trying to turn it to JSON, you will see a type of "opaque".

Opaque types are listed as "severely restricted" as explained in the fetch spec on whatwg.org.

> An opaque filtered response is a filtered response whose type is "opaque", url list is the empty list, status is 0, status message is the empty byte sequence, header list is empty, body is null, and trailer is empty.

They cannot currently be read when the type is opaque as explained on Google's docs on the opaque type.

> An opaque response is for a request made for a resource on a different origin that doesn't return CORS headers. With an opaque response, we won't be able to read the data returned or view the status of the request, meaning we can't check if the request was successful or not. With the current fetch() implementation, it's not possible to make requests for resources of a different origin from the window global scope.

Enable CORS support on your server

This can be environment-dependent or language-dependent. For example, you can change CORS settings within Nginx's environment by changing your server config, or you can specify headers within your application code such as in PHP.

I highly recommend reading the Mozilla documentation on CORS requests and also Access-Control-Allow-Origin.

An example in PHP:

<?php
header("Access-Control-Allow-Origin: *");  // "*" could also be a site such as http://www.example.com

Solution 2 - Javascript

I had the same problem. in my case it wasn't caused by the response type of 'opaque' as the solution pointed. This code cause an error with empty response, because 'fetch' doesn't accept responses with empty body :

return fetch(urlToUser, parameters)
.then(response => {
  return response.json()
})
.then((data) => {
  resolve(data)
})
.catch((error) => {
  reject(error)
})

Instead, in my case this works better :

return fetch(urlToUser, parameters)
.then(response => {
  return response.text()
})
.then((data) => {
  resolve(data ? JSON.parse(data) : {})
})
.catch((error) => {
  reject(error)
})

Gettting the text doesn't give the error even with the empty body. Then check if data exists and resolve. I hope it helps :-)

Solution 3 - Javascript

Lots of good responses but I chose this:

      const response = await fetch(url, {
        method: 'GET',
        headers: {
          Authorization: 'Bearer ' + accessToken
        }
      });
      const string = await response.text();
      const json = string === "" ? {} : JSON.parse(string);
      return json;

Solution 4 - Javascript

You need to have 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;
});

Solution 5 - Javascript

(for people coming later but dealing with this problem "Unexpected end of JSON input")

The problem in many times is server error or just invalid URL but you can't see it because all examples on internet how to work with fetch are missing one important part - the server or network failure.

The correct way how to deal with fetch is to test response if contains errors before conversion to json.

Check the part of the first then in example where resp.ok is tested:

async function fetchData() {
    return await fetch('https://your-server.com/some-NOt-existing-url/')
        .then(resp => {
            if (!resp.ok) {
                throw `Server error: [${resp.status}] [${resp.statusText}] [${resp.url}]`;
            }
            return resp.json();
        })
        .then(receivedJson => {
            // your code with json here...
        })
        .catch(err => {
            console.debug("Error in fetch", err);
            setErrors(err)
        });
}

Solution 6 - Javascript

Adding to Pibo's answer...

I dont know how this happened, but I solved it just by changing

return fetch(url, {
        mode: "no-cors" // <----------------
    })
    .then((res)=>{
        return res.text();
    })
    .then((data)=>{
        console.log(data);
        return new Promise((resolve, reject)=>{
            resolve(data ? JSON.parse(data) : {})
        })
    })

to

return fetch(url, {
        mode: "cors" // <----------------
    })
    .then((res)=>{
        return res.text();
    })
    .then((data)=>{
        console.log(data);
        return new Promise((resolve, reject)=>{
            resolve(data ? JSON.parse(data) : {})
        })
    })

Solution 7 - Javascript

You met with the CORS origin policy problem. To tackle this you need rights to access the server side API. In particular, you need to add a line in the header of php or another server endpoint:

<?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
?>

Also, make sure NOT to have in the header of your server endpoint:

header("Access-Control-Allow-Credentials" : true);

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

Solution 8 - Javascript

unexpected end of input

 // .then((response) => response.json()) .  // commit out this part

https://github.com/github/fetch/issues/268

fetch(url, {
    method: 'POST',
    body: JSON.stringify(requestPayload),			
    headers: {
        'Content-type': 'application/json; charset=UTF-8',
        Authorization: 'Bearer ' + token,
    },
})
    // .then((response) => response.json()) .  // commit out this part
    .then((json) => {
        console.log("response :- ", json);
        getCheckedInTrailersList();
    }).catch((error)=>{
        console.log("Api call error ", error.message);
        alert(error.message);
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - JavascriptKevBotView Answer on Stackoverflow
Solution 2 - JavascriptPiboView Answer on Stackoverflow
Solution 3 - Javascriptariel guzmanView Answer on Stackoverflow
Solution 4 - JavascriptRomanView Answer on Stackoverflow
Solution 5 - Javascriptmojmir.novakView Answer on Stackoverflow
Solution 6 - JavascriptUttkarsh PatelView Answer on Stackoverflow
Solution 7 - JavascriptRomanView Answer on Stackoverflow
Solution 8 - JavascriptKeshav GeraView Answer on Stackoverflow