You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

内容脚本fetch函数失效,报Unexpected end of JSON input错误求助

解决扩展内容脚本中fetch报错Unexpected end of JSON input的问题

嘿,这个问题我之前也碰到过类似的,咱们一步步来排查和解决~

首先,这个报错Uncaught (in promise) SyntaxError: Unexpected end of JSON input本质是你尝试用res.json()解析的内容不是有效的JSON,甚至可能是空字符串。弹窗里能正常工作,但内容脚本不行,核心原因是两者的运行上下文权限和环境有差异,咱们分情况来看:

第一步:先排查实际返回的响应内容

先别直接解析JSON,先把响应的状态码和原始内容打出来,搞清楚服务器到底返回了什么:

const getRequest = function (url) {
  return window.fetch(url, { method: 'GET' })
    .then(res => {
      // 先打印响应状态,看是否是200成功
      console.log('请求状态码:', res.status);
      // 先获取文本内容,而不是直接解析JSON
      return res.text();
    })
    .then(text => {
      console.log('服务器返回的原始内容:', text);
      // 再尝试解析JSON,捕获错误
      try {
        return JSON.parse(text);
      } catch (e) {
        console.error('解析JSON失败:', e);
        throw e;
      }
    });
}

运行后看控制台:

  • 如果返回的是空字符串,大概率是请求被浏览器拦截或者服务器没返回内容
  • 如果是HTML页面(比如403/404错误页),说明请求没成功,可能是权限或跨域问题
  • 如果是正常JSON但解析失败,那可能是格式问题(不过弹窗里能正常解析,这个概率低)

第二步:检查扩展权限配置

弹窗属于扩展的内部上下文(弹窗/后台),默认拥有扩展声明的所有权限;但内容脚本是注入到网页中的,它的fetch请求受网页上下文和扩展权限的双重限制。

打开你的manifest.json,确保你请求的目标URL已经添加到host_permissions里:

{
  "manifest_version": 3, // 如果你用的是v2,对应permissions字段
  "host_permissions": [
    "https://你的目标API域名/*" // 比如"https://api.example.com/*"
  ],
  // 其他扩展配置...
}

如果没加这个权限,Chrome等浏览器会拦截内容脚本的跨域请求,导致返回空内容,而Brave的权限策略可能更宽松,所以能正常运行。

第三步:用后台脚本代理请求(终极解决方案)

如果上面的方法都不行,那大概率是浏览器的安全策略(比如CORB跨域资源阻止)限制了内容脚本的请求。这时候可以用**扩展后台脚本(Service Worker)**来代理请求,因为后台脚本属于扩展的核心上下文,不受网页环境的限制:

1. 编写后台脚本(service-worker.js)

// 监听来自内容脚本的消息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  // 判断消息类型,处理fetch请求
  if (request.type === 'proxy-fetch') {
    fetch(request.url, { method: 'GET' })
      .then(res => res.json())
      .then(data => sendResponse({ success: true, data }))
      .catch(err => sendResponse({ success: false, error: err.message }));
    return true; // 告诉Chrome我们要异步发送响应
  }
});

2. 修改内容脚本的请求逻辑

const getRequest = function (url) {
  return new Promise((resolve, reject) => {
    // 给后台脚本发消息,请求代理fetch
    chrome.runtime.sendMessage(
      { type: 'proxy-fetch', url },
      (response) => {
        if (response.success) {
          resolve(response.data);
        } else {
          reject(new Error(response.error));
        }
      }
    );
  });
}

3. 更新manifest配置

确保后台脚本在manifest里正确注册:

{
  "manifest_version": 3,
  "background": {
    "service_worker": "service-worker.js"
  },
  "host_permissions": [
    "https://你的目标API域名/*"
  ],
  // 其他配置...
}

这样通过后台脚本代理请求,就能绕过内容脚本的上下文限制,基本能解决大部分跨域或权限导致的fetch问题。


内容的提问来源于stack exchange,提问作者Toxnyc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:53:44