[英]Access-Control-Allow-Origin error in a chrome extension
I have a chrome extension which monitors the browser in a special way, sending some data to a web-server. 我有一个chrome扩展程序,它以一种特殊的方式监视浏览器,将一些数据发送到Web服务器。 In the current configuration this is the localhost.
在当前配置中,这是本地主机。 So the content script contains a code like this:
因此,内容脚本包含如下代码:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(data)...
xhr.open('GET', url, true);
xhr.send();
where url parameter is 'http://localhost/ctrl?params' (or http://127.0.0.1/ctrl?params - it doesn't matter). 其中url参数为“ http:// localhost / ctrl?params”(或http://127.0.0.1/ctrl?params-无关紧要)。
Manifest-file contains all necessary permissions for cross-site requests. 清单文件包含跨站点请求的所有必要权限。
The extension works fine on most sites, but on one site I get the error: 该扩展程序在大多数站点上都可以正常运行,但是在一个站点上我得到了错误:
XMLHttpRequest cannot load http://localhost/ctrl?params. Origin http://www.thissite.com is not allowed by Access-Control-Allow-Origin.
I've tried several permissions which are proposed here ( *://*/*
, http://*/*
, and <all_urls>
), but no one helped to solve the problem. 我尝试了这里提出的几种权限(
*://*/*
, http://*/*
和<all_urls>
),但是没有人帮助解决该问题。
So, the question is what can be wrong with this specific site (apparently there may be another sites with similar misbehaviour, and I'd like to know the nature of this), and how to fix the error? 因此,问题是此特定站点可能有什么问题(显然可能还有其他行为类似的站点,我想知道其本质),以及如何解决该错误?
(tl;dr: see two possible workarounds at the end of the answer) (tl; dr:在答案末尾看到两个可能的解决方法)
This is the series of events that happens, which leads to the behavior that you see: 这是发生的一系列事件,导致您看到以下行为:
<script>
tag that asynchronously loads the Facebook Connect script: <script>
标记,用于异步加载Facebook Connect脚本: \n(function() {(function(){\n var e = document.createElement('script');
var e = document.createElement('script');\n e.type = 'text/javascript';
e.type ='text / javascript';\n e.src = document.location.protocol +
e.src = document.location.protocol +\n '//connect.facebook.net/en_US/all.js';
'//connect.facebook.net/en_US/all.js';\n e.async = true;
e.async = true;\n document.getElementById('fb-root').appendChild(e);
document.getElementById('fb-root')。appendChild(e);\n}());
}());\n
DOMContentLoaded
event fires. DOMContentLoaded
事件。 Since your content script uses "run_at" : "document_end"
, it gets injected and run at this time. "run_at" : "document_end"
,因此它将被注入并在此时运行。 load
event fires): load
事件触发后完成大部分工作): \nwindow.onload = function() {window.onload = function(){\n // code that eventually does the cross-origin XMLHttpRequest
//最终执行跨域XMLHttpRequest的代码\n};
};\n
load
event handler, which it adds with this snippet: load
事件处理程序,并在此代码段中添加该处理程序: \n(function() {(this is the first key part)(function(){\n var oldonload=window.onload;
var oldonload = window.onload;\n window.onload=function(){
window.onload = function(){\n // Run new onload code
//运行新的加载代码\n if(oldonload) {
if(oldonload){\n if(typeof oldonload=='string') {
if(typeof oldonload =='string'){\n eval(oldonload);
eval(oldonload);\n } else {
}其他{\n oldonload();
oldonload();\n }
}\n }
}\n };
};\n})();
})();\n
onload
property, oldonload
is your script's load handler. onload
属性,因此oldonload
是脚本的加载处理程序。 load
event handler fires. load
事件处理程序触发。 load
handler is run, which run its own code, and then invokes oldonload
. load
处理程序,该处理程序运行自己的代码,然后调用oldonload
。 (this is the second key part) load
handler, it's not running it in your script's isolated world , but in the page's "main world" . load
处理程序,因此它不是在脚本的隔离环境中运行 ,而是在页面的“主要世界”中运行 。 Only the script's isolated world has cross-origin XMLHttpRequest
access, so the request fails. XMLHttpRequest
访问,因此请求失败。 To see a simplified test case of this, see this page (which mimics http://www.wix.com ), which loads this script (which mimics Facebook Connect). 要查看此内容的简化测试用例,请参阅此页面 (模仿http://www.wix.com ),该页面加载此脚本 (模仿Facebook Connect)。 I've also put up simplified versions of the content script and extension manifest .
我还提出了内容脚本和扩展清单的简化版本。
The fact that your load
handler ends up running in the "main world" is most likely a manifestation of Chrome bug 87520 (the bug has security implications, so you might not be able to see it). 您的
load
处理程序最终在“主世界”中运行的事实很可能是Chrome错误87520的体现(该错误具有安全隐患,因此您可能看不到它)。
There are two ways to work around this: 有两种方法可以解决此问题:
"run_at" : "document_end"
and a load
event handler, you can use the default running time ( document_idle
, after the document loads) and just have your code run inline. "run_at" : "document_end"
和load
的事件处理程序,你可以使用默认的运行时间( document_idle
,文件加载后),只是有你的代码运行的内联。 load
event handler by setting the window.onload
property, use window.addEventListener('load', func)
. window.onload
属性来添加load
事件处理程序, window.addEventListener('load', func)
使用window.addEventListener('load', func)
。 That way your event handler will not be visible to the Facebook Connect, so it'll get run in the content script's isolated world. The access control origin issue you're seeing is likely manifest in the headers for the response (out of your control), rather than the request (under your control). 您看到的访问控制源问题很可能出现在响应(不在控件中)的标题中,而不是在请求(在控件中)的标头中。
Access-Control-Allow-Origin is a policy for CORS , set in the header. Access-Control-Allow-Origin是在标头中设置的CORS的策略。 Using PHP, for example, you use a set of headers like the following to enable CORS:
例如,使用PHP,您可以使用一组类似于以下的标头来启用CORS:
header('Access-Control-Allow-Origin: http://blah.com');
header('Access-Control-Allow-Credentials: true' );
header('Access-Control-Allow-Headers: Content-Type, Content-Disposition, attachment');
If sounds like that if the server is setting a specific origin in this header, then your Chrome extension is following the directive to allow cross-domain (POST?) requests from only that domain. 如果听起来像是服务器在此标头中设置特定来源,则说明您的Chrome扩展程序遵循该指令,仅允许来自该域的跨域(POST?)请求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.