fetch()意外的输入结束

时间:2017-08-15 16:15:53

标签: javascript json cors fetch-api

我正在使用fetch()从api服务器获取数据。我的错误看起来像这样:

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

你能告诉我我做错了吗。

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

7 个答案:

答案 0 :(得分:38)

no-cors请求跨域资源的响应为response type of 'opaque'。如果在尝试将响应变为JSON之前记录响应,则会看到一种“不透明”。

不透明类型为listed as "severely restricted"

  

不透明的过滤响应是过滤后的响应,其类型为“opaque”,url list为空列表,status为0,status消息为空字节序列,header list为空,body为null,预告片为空

当类型不透明时,它们当前无法读取。

  

不透明响应是针对不返回CORS头的不同源上的资源发出的请求。使用不透明的响应,我们将无法读取返回的数据或查看请求的状态,这意味着我们无法检查请求是否成功。使用当前的fetch()实现,不可能在窗口全局范围的不同来源上请求资源。

See Google's docs on the opaque type

答案 1 :(得分:8)

我有同样的问题。在我的情况下,这不是由解决方案所指出的“不透明”响应类型引起的。 这段代码导致响应为空的错误,因为'fetch'不接受响应为空的响应:

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

相反,就我而言,它效果更好:

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

即使正文为空,获取文本也不会给出错误。然后检查数据是否存在并解决。 希望对您有所帮助:-)

答案 2 :(得分:2)

您需要在php或其他服务器端点的标题中包含以下行:

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

使用POST请求的工作获取代码模型是:

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

答案 3 :(得分:2)

很多好的回应,但我选择了这个:

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

答案 4 :(得分:1)

(对于稍后来但处理这个问题“JSON 输入意外结束”的人)

很多时候的问题是服务器错误或只是无效的 URL,但您看不到它,因为互联网上如何使用 fetch 的所有示例都缺少一个重要部分 - 服务器或网络故障。

我认为处理 fetch 的正确方法是在转换为 json 之前测试响应是否包含错误。

在测试 then 的示例中检查第一个 it.ok 的部分:

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

(注意:it 只是从 Kotlin 借来的命名约定,它使 TypeScript/JavaScript 代码更短。它是表达式左侧任何内容的别名,因此在本例中为 response )

答案 5 :(得分:0)

您遇到了CORS原始政策问题。要解决此问题,您需要访问服务器端API的权限。特别是,您需要在php或其他服务器端点的标题中添加一行:

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

另外,请确保不要在服务器端点的标题中:

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

使用POST请求的工作获取代码模型是:

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

答案 6 :(得分:0)

意外的输入结束

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