Uncatch(in promise)SyntaxError:JSON输入意外结束

cyej8jka  于 2023-06-25  发布在  其他
关注(0)|答案(6)|浏览(268)

我正在尝试向服务器发送新的推送订阅,但遇到错误“Uncatch(in promise)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()函数中打印到屏幕上,并且我在google codelab的示例服务器中使用了该输出成功地接收了推送。
编辑:这里是JSON作为字符串,但我没有看到语法错误:

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

有什么想法吗?

drnojrws

drnojrws1#

这可能是由于端点没有在响应头中传递适当的参数而导致的问题。
在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
ekqde3dh

ekqde3dh2#

当我使用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获取数据时遇到的问题

gjmwrych

gjmwrych3#

这可能是因为你没有从服务器发送任何JSON,或者这可能是因为你发送了无效的JSON。
您的代码可能类似于res.end();

bfhwhh0e

bfhwhh0e4#

其中一个缺陷是,返回的数据不是JSON,而只是纯文本负载,而不考虑头设置。例如,通过以下方式以Express发送

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

而不是

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

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

nafvub8i

nafvub8i5#

等会看这里的人。我收到这个错误不是因为我的头,而是因为我没有递归地将响应体附加到字符串到稍后的JSON.parse。
按照MDN示例(我已经删除了他们示例中不直接相关的部分):

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

为了我的问题我不得不
1.在.then中使用命名函数(而不是anonymous()=>{})
1.递归地将结果追加到一起。
1.一旦done为真,就对总的附加结果执行其他操作
以防将来这对你有帮助,而你的问题与header无关,而是与初始JSON流响应的done值不为真有关。

t9aqgxwy

t9aqgxwy6#

我知道这个问题已经回答了,但我只是想补充一下我的想法。
当响应体为空并且respons.json()需要一个JSON字符串时,就会发生这种情况。确保API返回JSON格式的响应正文(如果必须的话)。

相关问题