如何在Tampermonkey脚本中执行JavaScript Fetch不被CORS策略拦截?
问题场景
在Tampermonkey用户脚本中运行以下代码时,遭遇CORS拦截:
var data="744483"; var url="https://example.com/test.php?data="+data; fetch(url).then(response => response.text()) .then((response) => {alert(response);})
报错信息:
Access to fetch at 'https://example.com/test.php?data=744483' from origin 'https://www.paxful.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Failed to load resource: net::ERR_FAILED
尝试添加mode: 'no-cors'后,代码能运行但无响应输出:
var data="744483"; var url="https://example.com/test.php?data="+data; fetch(url, { mode: 'no-cors'}).then(response => response.text()) .then((response) => {alert(response);})
原因分析
- 浏览器CORS政策禁止页面脚本直接发起跨域请求,除非目标服务器明确授权,因此原始fetch请求被拦截。
- 设置
mode: 'no-cors'后,浏览器会返回不透明响应(opaque response),这种响应的内容无法被脚本读取,因此alert无输出。
解决方法
使用Tampermonkey提供的GM_xmlhttpRequestAPI,这是扩展层面的请求方式,不受浏览器CORS政策限制,能正常获取并读取响应内容。
步骤1:添加权限声明
在脚本的元数据部分添加@grant GM_xmlhttpRequest,授权使用该API:
// ==UserScript== // @name 跨域请求处理 // @match https://www.paxful.com/* // @grant GM_xmlhttpRequest // ==/UserScript==
步骤2:替换请求代码
用GM_xmlhttpRequest替代fetch,示例代码:
(function() { 'use strict'; var data = "744483"; var url = "https://example.com/test.php?data=" + data; GM_xmlhttpRequest({ method: "GET", url: url, onload: function(res) { // 获取响应内容并弹出 alert(res.responseText); }, onerror: function(err) { // 处理请求失败场景 alert("请求出错:" + err.message); } }); })();
补充说明
如果你有权限修改目标服务器(example.com)的配置,也可以在test.php中添加CORS响应头实现授权:
// 仅允许指定域名跨域请求 header("Access-Control-Allow-Origin: https://www.paxful.com"); // 或者允许所有域名(不推荐生产环境使用) // header("Access-Control-Allow-Origin: *");
但如果无法控制服务器,使用GM_xmlhttpRequest是最可靠的解决方案。
内容的提问来源于stack exchange,提问作者Ryan Newman

