问题
In the response HTML of a website, with a domain like http://www.example.com
, there are many javascript files referenced. One of them references a javascript file on a different domain, and this script tag has the crossorigin="anonymous"
attribute set:
<script crossorigin="anonymous" src="//cdn.example.net/script.js"></script>
I've attempted to redirect the request to another url using a Google Chrome extension:
chrome.webRequest.onBeforeRequest.addListener(function(info) {
return {
redirectUrl: "http://example.org/custom.js"
};
}, {
urls: [
"*://cdn.example.net/script.js"
],
types: ["script"]
}, ["blocking"]);
However, when I try and load the site I get an error in the javascript console:
Redirect at origin
http://cdn.example.net
has been blocked from loading by Cross-Origin Resource Sharing policy: Received an invalid response.
Originhttp://www.example.com
is therefore not allowed access.
If I intercept the response HTML manually (outside of Chrome) and remove the attribute crossorigin="anonymous"
it works as expected.
I have the file at http://example.org/custom.js
set to send:
Access-Control-Allow-Origin: *
I have also tried removing / modifying the response headers from www.example.com
but this does not seem to make a difference. The response headers ( for reference ) from the main frame are:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Vary: Accept-Encoding
Status: 200 OK
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-UA-Compatible: chrome=1
Cache-Control: no-cache, no-store
X-Frame-Options: SAMEORIGIN
P3P: CP="NOI DSP COR NID ADMa OPTa OUR NOR"
Content-Encoding: gzip
There are other javascript files that load after this one, and depend on it, and I'd like to leave them as they are.
Again, the main issue really seems to be the crossorigin="anonymous"
tag ( which from what I can tell supposedly has the primary purpose of choosing whether error information will be exposed )
How can I write a Google Chrome extension to override the javascript that is executed from this source?
回答1:
Your attempted solutions don't work, because the only relevant headers for CORS are those that are served by the original resource. If this CORS check succeeds, then the redirects are checked and so on.
However, it appears that the initial CORS check failed already..I've reported this bug at https://code.google.com/p/chromium/issues/detail?id=387198.
There is a work-around. Since Chromium 35.0.1911.0, you can redirect requests at the chrome.webRequest.onHeadersReceived event. Redirecting a cross-origin request at this stage seems to work if you set the access-control-allow-origin: *
together with redirectUrl
. A small disadvantage of this approach is that the request is not immediately redirected, but only after receiving a response from the origin request. If the original request results in an error, e.g. a 404, then your redirect won't happen at all. Nevertheless, it is the only way to get the desired effect until the bug is fixed.
chrome.webRequest.onHeadersReceived.addListener(function(info) {
return {
responseHeaders: info.responseHeaders.concat([{
name: 'access-control-allow-origin',
value: '*'
}]),
redirectUrl: "http://localhost:2222/custom.js"
};
}, {
urls: [
"*://example.net/script.js"
],
types: ["script"]
}, ["blocking", "responseHeaders"]);
Note: Regardless of the method, the target of the redirect must also include an appropriate access-control-allow-origin
header, or the request will still be aborted with the following error:
Redirect at origin '
http://example.net
' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4444
' is therefore not allowed access.
来源:https://stackoverflow.com/questions/24318711/how-can-i-override-javascript-files-referenced-with-the-crossorigin-anonymous