Chrome扩展本地服务器响应数据无法被background.js接收问题
问题原因
你无法获取服务器返回内容,核心问题出在3处:
- 前端
fetch拿到的response是HTTP响应流对象,没有调用解析方法读取响应体,自然拿不到response.send()返回的JSON数据 - 请求路径末尾多了冗余斜杠,和后端定义的
/login路由不匹配,极易触发301跳转导致POST请求降级、参数丢失 - 后端代码缺少异常捕获、跨域头配置,Header解析逻辑冗余,容易出现接口挂死、跨域拦截的问题
修复步骤
1. 修正background.js请求逻辑
原来的代码只判断了状态码,没有解析响应体,错误捕获为空,出问题无法定位。替换为以下代码:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.message === 'login') { const user1 = request.payload.email const user2 = request.payload.password // 注意去掉url末尾的斜杠,和后端路由严格匹配 fetch('http://localhost:3000/login', { method: 'POST', headers: { "Content-Type": "application/json", 'auth': `${user1}:${user2}` } }) .then(async response => { // 解析JSON格式的响应体,解析失败时返回空对象避免代码报错 const resData = await response.json().catch(() => ({})) if (response.status === 200) { console.log('服务器返回数据:', resData) // 此处可直接拿到{message: xxx}的返回内容 sendResponse({status: 'success', data: resData}) } else { console.log('请求失败,状态码:', response.status, '返回信息:', resData) sendResponse({status: 'fail'}) } }) .catch(err => { // 必须打印错误日志,方便定位跨域、网络断开类问题 console.error('请求异常:', err) sendResponse({status: 'error'}) }) return true } });
2. 修正后端接口逻辑
后端代码需要补全跨域配置、异常捕获,简化Header解析逻辑,替换为以下代码:
// 跨域配置必须放在所有路由定义之前 app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Headers', 'Content-Type,auth') res.header('Access-Control-Allow-Methods', 'POST') // 直接响应浏览器的OPTIONS预检请求 if (req.method === 'OPTIONS') return res.sendStatus(200) next() }) app.post('/login', async (request, response) => { try { // 直接读取auth头,不需要JSON.stringify等冗余处理 const authHeader = request.headers.auth if (!authHeader) return response.status(400).send({message: '缺少鉴权头'}) const [cred1, cred2] = authHeader.split(':') if (!cred1 || !cred2) return response.status(400).send({message: '鉴权参数格式错误'}) const userRes = await getuser(cred1) const resobj = userRes.pop() // 补全用户不存在的分支判断,避免读取undefined属性报错 if (!resobj) return response.status(404).send({message: '用户不存在'}) const respass = resobj.password const decipher = cryptoJS.AES.decrypt(respass, key); const decipher2 = decipher.toString(cryptoJS.enc.Utf8); if (cred2 === decipher2 ) { response.status(200).send({message: respass}) } else { response.status(404).send({message: '密码错误'}) } } catch (err) { // 捕获所有运行时异常,避免接口挂死无响应 console.error('登录接口异常:', err) response.status(500).send({message: '服务内部错误'}) } })
3. 检查扩展manifest配置
确保manifest.json中已经配置了本地服务的访问权限,否则扩展会拦截请求:
{ "manifest_version": 3, "host_permissions": ["http://localhost:3000/*"], // 其余配置保持原有内容即可 }
排查验证顺序
- 打开Chrome扩展管理页,找到对应扩展的「背景页」调试入口,切换到Network面板查看login请求的实际状态、响应内容,优先排查跨域、404、500类错误
- 查看后端服务控制台,确认请求正常到达、没有抛出运行时异常
- 代码修改完成后重载扩展、重启后端服务,即可在前端正常读取到服务器返回的内容
内容的提问来源于stack exchange,提问作者VGob
相关产品推荐
相关产品推荐

