简体   繁体   English

Chrome扩展程序中的Access-Control-Allow-Origin错误

[英]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: 这是发生的一系列事件,导致您看到以下行为:

  1. http://www.wix.com/ begins to load http://www.wix.com/开始加载
  2. It has a <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
  3. Once the HTML (but not resources, including the Facebook Connect script) of the wix.com page loads, the DOMContentLoaded event fires. 一旦加载了wix.com页面的HTML(但未加载资源,包括Facebook Connect脚本),则将触发DOMContentLoaded事件。 Since your content script uses "run_at" : "document_end" , it gets injected and run at this time. 由于您的内容脚本使用"run_at" : "document_end" ,因此它将被注入并在此时运行。
  4. Your content script runs the following code (as best as I can tell, it wants to do the bulk of its work after the load event fires): 您的内容脚本运行以下代码(据我所知,它最好在load事件触发后完成大部分工作):
    \nwindow.onload = function() { window.onload = function(){\n  // code that eventually does the cross-origin XMLHttpRequest //最终执行跨域XMLHttpRequest的代码\n}; };\n
  5. The Facebook Connect script loads, and it has its own load event handler, which it adds with this snippet: Facebook Connect脚本会加载,并且具有自己的load事件处理程序,并在此代码段中添加该处理程序:
    \n(function() { (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
    (this is the first key part) Since your script set the onload property, oldonload is your script's load handler. (这是第一个关键部分) 由于脚本设置了onload属性,因此oldonload是脚本的加载处理程序。
  6. Eventually, all resources are loaded, and the load event handler fires. 最终,所有资源都被加载,并且load事件处理程序触发。
  7. Facebook Connect's load handler is run, which run its own code, and then invokes oldonload . 运行Facebook Connect的load处理程序,该处理程序运行自己的代码,然后调用oldonload (this is the second key part) Since the page is invoking your 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: 有两种方法可以解决此问题:

  1. Instead of using "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 ,文件加载后),只是有你的代码运行的内联。
  2. Instead of adding your 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. 这样,您的事件处理程序将对Facebook Connect不可见,因此它将在内容脚本的孤立世界中运行。

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.

相关问题 Google Chrome扩展程序错误 - 访问控制 - 允许 - 来源 - Google Chrome Extension error - Access-Control-Allow-Origin Chrome 中的 Access-Control-Allow-Origin 错误 - Access-Control-Allow-Origin error in Chrome Access-Control-Allow-Origin不允许“Chrome扩展程序”的含义? - Meaning of “Chrome-extension is not allowed by Access-Control-Allow-Origin”? Chrome扩展程序-Access-Control-Allow-Origin不允许使用 - Chrome Extension - Not allowed by Access-Control-Allow-Origin Chrome扩展程序后台页面有时会返回错误Access-Control-Allow-Origin(通常在Windows XP上) - Chrome Extension background page returns error Access-Control-Allow-Origin only sometimes (usually on Windows XP) Access-Control-Allow-Origin不允许使用Chrome Origin null - Chrome Origin null is not allowed by Access-Control-Allow-Origin Chrome 上的 access-control-allow-origin 不允许 Origin null - Origin null is not allowed by access-control-allow-origin on Chrome Chrome扩展程序20小时后没有“Access-Control-Allow-Origin”标题 - Chrome extension No 'Access-Control-Allow-Origin' header after 20 hours “尝试与Chrome扩展程序中的Google Contacts API进行交互时,不会出现”Access-Control-Allow-Origin“标题 - “No 'Access-Control-Allow-Origin' header is present” when trying to interact with Google Contacts API from Chrome extension Chrome / IE,AngularJS和Access-Control-Allow-Origin - Chrome / IE, AngularJS, and Access-Control-Allow-Origin
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM