saber酱的抱枕

生于忧患,死于安乐

09/2
14:37
软件

Chrome 扩展允许任意跨域的办法

浏览器里是不允许跨域的,如果服务器没有指定 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 : *。(如果此请求本来就有这个标头,就先删掉然后添加)

可以根据自己需要把网址范围 *://*/* 修改一下,避免影响所有网络请求。

Chrome 扩展允许任意跨域的办法