【问题标题】:Uncaught (in promise) SyntaxError: Unexpected end of JSON input未捕获(承诺中)SyntaxError:JSON 输入意外结束
【发布时间】:2017-09-07 19:33:26
【问题描述】:

我正在尝试向我的服务器发送新的推送订阅,但遇到错误“未捕获(承诺中)SyntaxError:JSON 输入的意外结束”,控制台说它在我的索引页面的第 1 行,这显然是不是这样的。

我怀疑发生问题的函数(因为当我注释掉它时不会抛出错误)是sendSubscriptionToBackEnd(subscription),它在下面被调用:

function updateSubscriptionOnServer(subscription) {
  const subscriptionJson = document.querySelector('.js-subscription-json');
  const subscriptionDetails = document.querySelector('.js-subscription-details');

  if (subscription) {
    subscriptionJson.textContent = JSON.stringify(subscription);
    sendSubscriptionToBackEnd(subscription);
    subscriptionDetails.classList.remove('is-invisible');
  } else {
    subscriptionDetails.classList.add('is-invisible');
  }
}

函数本身(在上述函数之前):

 function sendSubscriptionToBackEnd(subscription) {
  return fetch('/path/to/app/savesub.php', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(subscription)
  })
  .then(function(response) {
    if (!response.ok) {
      throw new Error('Bad status code from server.');
    }

    return response.json();
  })
  .then(function(responseData) {
    if (!(responseData.data && responseData.data.success)) {
      throw new Error('Bad response from server.');
    }
  });
}

我尝试在 fetch 调用中用双引号替换单引号,但结果相同。

我知道应该填充 JSON,因为它会在 updateSubscriptionOnServer() 函数中使用 subscriptionJson.textContent = JSON.stringify(subscription); 打印到屏幕上,并且我在 google codelab 的示例服务器中使用该输出来成功接收推送。

编辑:这是作为字符串的 JSON,但我没有看到语法错误:

{"endpoint":"https://fcm.googleapis.com/fcm/send/dLmthm1wZuc:APA91bGULRezL7SzZKywF2wiS50hXNaLqjJxJ869y8wiWLA3Y_1pHqTI458VIhJZkyOsRMO2xBS77erpmKUp-Tg0sMkYHkuUJCI8wEid1jMESeO2ExjNhNC9OS1DQT2j05BaRgckFbCN","keys":{"p256dh":"BBz2c7S5uiKR-SE2fYJrjPaxuAiFiLogxsJbl8S1A_fQrOEH4_LQjp8qocIxOFEicpcf4PHZksAtA8zKJG9pMzs=","auth":"VOHh5P-1ZTupRXTMs4VhlQ=="}}

有什么想法吗??

【问题讨论】:

  • 您能否向我们提供服务器的响应?
  • 也许问题是,您使用JSON.stringify() 而不是JSON.parse()
  • 你的 JSON 是什么样子的,好像是语法错误
  • 我同意亚历克斯。忘了你用过POST
  • @alexkucksdorf,我收到 JSON.parse() 时不会在服务器端使用它吗?我正在尝试在此处发送代码中的数据。

标签: javascript json web-push


【解决方案1】:

这可能是端点未在响应标头中传递适当参数的问题。

在 Chrome 的控制台中,在 Network 选项卡中,检查端点发送的标头,它应该包含以下内容: Example of proper response to allow requests from localhost and cross domains requests

要求 API 开发人员将其包含在标头中:

"Access-Control-Allow-Origin" : "*", 
"Access-Control-Allow-Credentials" : true 

【讨论】:

  • 我更改了返回 http 200 而不是 http 2004 状态代码的服务器端点,并以这种方式解决了它。
【解决方案2】:

当我使用 Express.js 运行服务器并使用 Brave 浏览器时,这也发生在我身上。就我而言,这是 COR 问题。我做了以下事情,它解决了我的问题: (因为这是一个 Express 框架,所以我使用的是 app.get)

-在服务器端:

 res.set({
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*",
    });

-在客户端我使用 Fetch 获取数据但禁用了 CORS 选项

// mode: "no-cors" //disabled this in Fetch

这解决了我使用 Express 获取数据的问题

【讨论】:

    【解决方案3】:

    这可能是因为您没有从服务器发送任何 JSON 要么 这可能是因为您发送的 JSON 无效。

    您的代码可能如下所示 res.end();

    【讨论】:

      【解决方案4】:

      对于以后看这里的人。我收到此错误不是因为我的标头,而是因为我没有将响应正文递归地附加到 JSON.parse 的字符串。

      根据MDN example(我已经删除了他们示例中不立即相关的一些部分):

      reader.read().then(function processText({ done, value }) {
          if (done) {
            console.log("Stream complete");
            return;
          }
          result += chunk;
          return reader.read().then(processText);
        });

      对于我的问题,我不得不

      1. 在 .then 中使用命名函数(不是匿名 ()=>{})
      2. 以递归方式将结果附加在一起。
      3. 一旦完成,对总附加结果执行其他操作

      以防万一这对您将来有帮助,并且您的问题与标头无关,而是与初始 JSON 流响应中的 done 值不正确有关。

      【讨论】:

        【解决方案5】:

        其中一个陷阱是返回的数据不是 JSON,而只是纯文本有效负载,而不管标头设置如何。 IE。通过类似的方式在 Express 中发送

        res.send({a: "b"});
        

        而不是

        res.json({a: "b"});
        

        会返回这个令人困惑的错误。不容易在网络活动中检测到,因为它看起来很合法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-17
          • 1970-01-01
          • 2017-04-20
          • 1970-01-01
          • 2020-01-08
          • 1970-01-01
          • 2023-03-23
          • 2021-01-09
          相关资源
          最近更新 更多