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

Chrome扩展:background.js发送XHR至Node.js服务器的问题咨询

解决Chrome扩展跨域请求与后台脚本API问题

核心误解澄清

Chrome扩展的后台脚本(Manifest V2的背景页/Manifest V3的Service Worker)并非不支持网络请求,只是API使用有版本差异:

  • Manifest V2的背景页是普通浏览器环境,完全支持XMLHttpRequest;
  • Manifest V3的Service Worker属于无DOM的隔离环境,不支持XMLHttpRequest,需使用标准fetch API。

最优解决方案:后台脚本代理请求

由于内容脚本(content.js)运行在网页上下文,受CORS限制,而后台脚本属于扩展上下文,不受网页CORS约束,因此最佳方案是让content.js通过消息通信,委托后台脚本发送请求。


1. 适配Manifest V3(推荐版本)

后台脚本(background.js,Service Worker环境)

使用fetch实现请求逻辑,并监听来自content.js的消息:

// 向服务器发送请求的函数
async function sendToServer(message) {
  try {
    const res = await fetch('http://localhost:3000/data', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      },
      body: JSON.stringify(message)
    });
    
    if (!res.ok) throw new Error(`请求失败:${res.status}`);
    return await res.json();
  } catch (err) {
    console.error('服务器请求出错:', err);
    return null;
  }
}

// 监听来自content.js的消息
chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
  if (req.action === 'callServer') {
    sendToServer(req.msg).then(sendResponse);
    return true; // 告知Chrome需异步返回响应
  }
});
内容脚本(content.js)

通过消息API触发后台请求:

chrome.runtime.sendMessage(
  { action: 'callServer', msg: { message: 'Hello' } },
  (response) => {
    if (response) console.log('服务器响应:', response.response);
  }
);

2. 适配Manifest V2(旧版本)

后台配置(manifest.json)

确保背景页为普通HTML页面:

"background": {
  "page": "background.html"
}
后台脚本(background.js)

可直接使用XMLHttpRequest或fetch:

// 使用XHR的示例
function sendToServer(message) {
  const xhr = new XMLHttpRequest();
  xhr.open('POST', 'http://localhost:3000/data', true);
  xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
      const res = JSON.parse(xhr.responseText);
      console.log(res.response);
      // 可通过chrome.runtime.sendMessage回传给content.js
    }
  };
  xhr.send(JSON.stringify(message));
}

// 监听content.js消息逻辑同V3版本

3. 服务器端代码修复

你的服务器代码存在两个关键问题:

  • 模板字符串使用单引号,导致变量无法解析;
  • 未处理浏览器预检OPTIONS请求,会导致content.js直接请求时CORS报错。

修复后的服务器代码:

const http = require('http');
const server = http.createServer((req, res) => {
  // 处理OPTIONS预检请求
  if (req.method === 'OPTIONS') {
    res.writeHead(200, {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type'
    });
    res.end();
    return;
  }

  if (req.method === 'POST' && req.url === '/data') {
    let body = '';
    req.on('data', chunk => body += chunk.toString());
    req.on('end', () => {
      const receivedMsg = JSON.parse(body).message;
      console.log(`Received message: ${receivedMsg}`); // 改用反引号解析变量
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ 
        response: `Server received: ${receivedMsg}` // 修复模板字符串
      }));
    });
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Not Found');
  }
});

server.listen(3000, () => console.log('Server running on port 3000'));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 13:37:04