Firefox中内容脚本向localhost发送fetch请求被阻止的解决方法
问题描述
我在http://localhost:8081运行了一个简易HTTP服务器,包含GET路由/tts,并返回以下CORS响应头:
self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "*") self.send_header("Access-Control-Allow-Headers", "*")
我编写的WebExtension在https://somedomain.com/*域名上执行内容脚本,脚本中运行:
fetch("http://localhost:8081/tts?text=test").catch(console.error)
但请求既没出现在开发者工具网络面板,也没到达服务器,控制台报错:TypeError: NetworkError when attempting to fetch resource.
manifest文件相关配置如下:
{ "manifest_version": 2, "content_scripts": [{ "matches": ["https://somedomain.com/*"], "js": ["content-script.js"] }], "permissions": [ "https://somedomain.com/*", "http://localhost:8081/*", "http://localhost:8081/tts*", "http://localhost:8081/tts/*", "http://localhost:8081/tts?*", "http://localhost:8081/tts?text=*", "tabs" ], ... }
已知情况:
- 服务器运行正常,在
somedomain.com控制台手动执行上述fetch请求可正常工作 - Chrome中测试同一扩展可正常运行,仅Firefox出现问题
- 从后台脚本发送请求也能正常工作,仅Firefox内容脚本中请求失败
解决方案
1. 修改Firefox本地扩展访问配置
Firefox默认限制内容脚本访问本地资源(包括localhost),需手动开启权限:
- 打开Firefox的
about:config页面 - 搜索配置项
extensions.webextensions.localhost_access - 将该选项的值改为
true
修改后重启浏览器,内容脚本的fetch请求即可正常发送到本地服务器。
2. 简化Manifest权限配置
Manifest中不需要重复添加多个localhost相关权限,保留"http://localhost:8081/*"即可,其余冗余权限可删除,简化后的权限配置如下:
"permissions": [ "https://somedomain.com/*", "http://localhost:8081/*", "tabs" ],
3. 备选方案:通过后台脚本转发请求
如果不想修改浏览器全局配置,可借助后台脚本中转请求(后台脚本不受Firefox本地资源访问限制):
内容脚本代码
// 向后台脚本发送请求消息 browser.runtime.sendMessage({ type: "fetchTTS", text: "test" }).then(response => { console.log("请求结果:", response); }).catch(console.error);
后台脚本代码
// 监听内容脚本的消息 browser.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === "fetchTTS") { // 后台脚本执行fetch请求 fetch(`http://localhost:8081/tts?text=${encodeURIComponent(message.text)}`) .then(res => res.text()) // 根据服务器返回格式选择res.json()或res.text() .then(data => sendResponse(data)) .catch(err => sendResponse({ error: err.message })); return true; // 标记为异步响应,避免消息通道提前关闭 } });
内容的提问来源于stack exchange,提问作者Forivin
相关产品推荐
相关产品推荐

