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

Chrome扩展调用第三方API遇CORS拦截问题求助

解决Chrome扩展Content Script调用API的CORS问题

你的问题出在Content Script的运行上下文:Content Script是注入到Google搜索页面的上下文里的,发起请求时会带上https://www.google.com的Origin,触发浏览器的CORS检查——哪怕你在manifest里加了API的权限,这个权限仅对扩展的特权上下文(比如后台脚本、弹出页)生效,Content Script无法直接使用。

用no-cors模式虽然能绕过CORS,但会限制你读取响应内容,完全达不到需求。

正确解决方案:用后台脚本(Background Script)发起API请求

后台脚本属于扩展的独立特权上下文,不受页面CORS限制,且已在manifest中声明了API访问权限,是最稳妥的解决方式。

步骤1:修改manifest.json,添加后台脚本配置

在原有配置中加入background字段:

{
  "manifest_version": 2,
  "name": "Test",
  "description": "Test extension",
  "version": "1.0.0",
  "permissions": [
    "https://myapi.test/*",
    "tabs",
    "notifications"
  ],
  "icons": {
    "128" : "img/icon_128.png"
  },
  "content_scripts": [
    {
      "js": ["content_script.js"],
      "matches": ["https://www.google.com/search*"]
    }
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}

步骤2:修改content_script.js,改为向后台发送消息

把原有的fetch逻辑替换为发送提取到的URL给后台,由后台处理API请求:

const items = document.querySelectorAll('div[jscontroller][jsaction][data-ved]');
items.forEach(item => {
    const url = item.querySelector('a');
    if (!url) return;
    const href = url.getAttribute("href");
    if (!href || href.startsWith('/search') || href.includes('#') || href.startsWith('/preferences')) return;

    // 将URL发送给后台脚本处理
    chrome.runtime.sendMessage({
        type: 'fetchUrlInfo',
        url: encodeURIComponent(href)
    }, (response) => {
        if (response?.success) {
            // 可在此处根据返回的数据更新页面(比如插入到搜索结果中)
            console.log('API返回数据:', response.data);
        } else {
            console.error('请求失败:', response?.error);
        }
    });
});

步骤3:新建background.js,处理API请求

在后台脚本中接收消息,发起API请求后将结果返回给Content Script:

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.type === 'fetchUrlInfo') {
        fetch('https://myapi.test/url_info', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                url: request.url
            })
        })
        .then(res => {
            if (res.status !== 200) {
                throw new Error(`请求失败,状态码:${res.status}`);
            }
            return res.json();
        })
        .then(data => {
            sendResponse({ success: true, data });
        })
        .catch(error => {
            console.error(error);
            sendResponse({ success: false, error: error.message });
        });
        // 异步请求需返回true,保持sendResponse可用
        return true;
    }
});

为什么这个方法有效?

后台脚本运行在扩展自身的独立上下文,不属于Google页面的一部分。Chrome会根据manifest中声明的permissions直接允许它访问https://myapi.test/*,不会触发任何CORS检查,完美解决你的问题。

补充:不推荐的替代方案

如果硬要在Content Script中发起请求,只能修改API服务器,添加CORS响应头允许https://www.google.com:

Access-Control-Allow-Origin: https://www.google.com

但这个方案存在明显问题:

  1. Google有大量子域名(如google.co.uk、google.com.hk),无法全部添加;
  2. 开放任意Google域名访问API,存在安全风险。

因此优先选择后台脚本的解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:46:02