09/2
2020
浏览器里是不允许跨域的,如果服务器没有指定 Access-Control-Allow-Origin
字段,那么浏览器会阻止向服务器发起的任何跨域请求。
如果服务器指定了 Access-Control-Allow-Origin
,则浏览器会根据它的设置,只允许它指定的那些域名进行跨域请求。
特别的,如果 Access-Control-Allow-Origin
的值是 *
,表示服务器接受任意跨域请求。
以前,如果我们制作了一个 Chrome 扩展,它的前台、后台代码都可以无视跨域限制,因为扩展有特权嘛。但是从 Chrome 85 开始,扩展的前台不允许跨域了,只允许后台跨域。
但是后台可以修改网络请求,我们给每个请求的 response headers 都添加 Access-Control-Allow-Origin : *
,那么前台发出的所有请求都可以跨域。
先在 manifest.json 里申请权限:
"permissions": ["webRequest", "webRequestBlocking", "*://*/*" ]
然后在后台代码(background.js)里修改网络请求:
function removeMatchingHeaders(headers: any, regex: any) {
for (var i = 0, header; (header = headers[i]); i++) {
if (header.name.match(regex)) {
headers.splice(i, 1);
console.log('Removing header "' + header.name + '":"' + header.value + '"');
return;
}
}
}
function responseListener(details: any) {
removeMatchingHeaders(details.responseHeaders, /access-control-allow-origin/i);
details.responseHeaders.push({ name: 'Access-Control-Allow-Origin', value: '*' });
return { responseHeaders: details.responseHeaders };
}
chrome.webRequest.onHeadersReceived.addListener(responseListener, {
urls: ['*://*/*']
}, [
'blocking',
'responseHeaders',
'extraHeaders'
]);
原理就是使用 chrome.webRequest.onHeadersReceived
API,检查每一个返回的请求头,添加 Access-Control-Allow-Origin : *
。(如果此请求本来就有这个标头,就先删掉然后添加)
可以根据自己需要把网址范围 *://*/*
修改一下,避免影响所有网络请求。