Javascript 在本地文件系统上绕过 Chrome Access-control-allow-origin?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4742467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:52:05  来源:igfitidea点击:

Circumventing Chrome Access-control-allow-origin on the local file system?

javascriptjquerygoogle-chromesame-origin-policy

提问by user210099

I've read the other same origin policy topics here on SO, but I haven't seen any solutions related to the local file system.

我已经在 SO 上阅读了其他同源策略主题,但我还没有看到任何与本地文件系统相关的解决方案。

I have a web app (In a loose sense of the word) that must be local served. I am trying to load a large amount of data in after the user has loaded the page, depending on what they are doing on the webpage. In Firefox 3.5 and IE8 I am able to use jQuery's AJAX() and GetScript() methods to do this, but in Chrome this fails due to the Same Origin Policy.

我有一个必须在本地提供的网络应用程序(从广义上讲)。我试图在用户加载页面后加载大量数据,具体取决于他们在网页上做什么。在 Firefox 3.5 和 IE8 中,我可以使用 jQuery 的 AJAX() 和 GetScript() 方法来执行此操作,但在 Chrome 中由于同源策略而失败。

XMLHttpRequestcannot load file://test/testdir/test.js. Origin nullis not allowed by Access-Control-Allow-Origin.

XMLHttpRequest无法加载file://test/testdir/test.js。原产地null是不允许的by Access-Control-Allow-Origin

This happens when I do something simple like

当我做一些简单的事情时会发生这种情况

$.getScript("test.js");

This functions perfectly well in IE & Firefox.

这在 IE 和 Firefox 中运行良好。

After reading a bunch about this, I decided to try writing directly into the head of the document. In the console in Chrome I typed the following:

在阅读了大量关于此的内容后,我决定尝试直接写入文档的头部。在 Chrome 的控制台中,我输入了以下内容:

var head = document.getElementsByTagName("head")[0];  
var script =document.createElement('script');   
script.id = 'uploadScript';  
script.type = 'text/javascript';  
script.src = "upload.js";   
head.appendChild(script);

This works fine when pasted in the console- the <script...test.js</script>element is added to the head, evaluated, and content loaded into the DOM.

这在粘贴到控制台时工作正常 -<script...test.js</script>元素被添加到头部,评估,并将内容加载到 DOM 中。

I thought this was successful, until I put this code into a function call. The same exact code, when called from a function, adds the element to the but does not evaluate the JavaScript file. I can not figure out why. If I use Chrome's console to stop execution in the method that it is adding the element to the and run the above code, it does not evaluate it. However, if I unpause the execution and run the exact same code (pasting it in the console window) it works. I'm at a loss to explain this. Has anyone dealt with this before?

我以为这是成功的,直到我将此代码放入函数调用中。相同的代码,当从函数调用时,将元素添加到 ,但不评估 JavaScript 文件。我不明白为什么。如果我使用 Chrome 的控制台在它添加元素的方法中停止执行并运行上面的代码,它不会评估它。但是,如果我取消暂停执行并运行完全相同的代码(将其粘贴到控制台窗口中),它就可以工作。我不知道如何解释这一点。有没有人处理过这个问题?

I've read up on the following SO posts, but they are not describing the problem that I have:

我已经阅读了以下 SO 帖子,但它们并没有描述我遇到的问题:

Ways to circumvent the same-origin policy
XMLHttpRequest Origin null is not allowed Access-Control-Allow-Origin for file:/// to file:/// (Serverless)
Cross-site XMLHttpRequest

绕过同源策略的方法
XMLHttpRequest Origin null is not allowed Access-Control-Allow-Origin for file:/// to file:/// (Serverless)
Cross-site XMLHttpRequest

Again, my last resort is to load all the data at the webpage's load- This can cause up to a 10 second delay in loading the webpage that is unnecessary for 90% of the app's users.

同样,我最后的手段是在网页加载时加载所有数据 - 这可能会导致加载网页延迟 10 秒,这对于 90% 的应用程序用户来说是不必要的。

Thanks for any suggestions/alternatives!!!

感谢您的任何建议/替代方案!!!

采纳答案by user210099

I thinkI've figured it out.

我已经想通了。

All I really needed to do was add a callback into my <script>tag. Final code:

我真正需要做的就是在我的<script>标签中添加一个回调。最终代码:

I have an element named next... So, in the $("#next").click()function I have the following code. This only gets executed if they click "next".

我有一个名为 next 的元素...所以,在$("#next").click()函数中我有以下代码。只有当他们点击“下一步”时才会执行。

//remove old dynamically written script tag-    
       var old = document.getElementById('uploadScript');  
   if (old != null) {  
     old.parentNode.removeChild(old);  
     delete old;  
   } 

   var head = document.getElementsByTagName("head")[0];  
   script = document.createElement('script');  
   script.id = 'uploadScript';  
   script.type = 'text/javascript';  
   script.src = 'test/' + scope_dir + '/js/list.js';  
   script.onload = refresh_page;    
   head.appendChild(script);  


function refresh_page(){  
   //perform action with data loaded from the .js file.  
}  

This seems to work, and allows Chrome to dynamically load .js files on the local file system while circumventing the access-control-allow-origin policy I ran into while trying to use jQuery functions.

这似乎有效,并允许 Chrome 在本地文件系统上动态加载 .js 文件,同时规避我在尝试使用 jQuery 函数时遇到的访问控制允许来源策略。

回答by peter

Ok, done a lot of fiddling and wasted a lot of time. But I got it figured. The solution in my last answer works fine for Chrome, and for Mozilla. But it does not work for blessed IE, because IE will not fire the onload event: it thinks it has dealt with all the onloads in this file and you can't get it to do another one. However, IE is quite happy to load the file up using the JQuery getScript function (which Chrome will not permit because of the ccess-control-allow-origin policy) -- you will need the JQuery libraries for this to work. So here is what I ended up with:

好吧,做了很多摆弄,浪费了很多时间。但我想通了。我上一个答案中的解决方案适用于 Chrome 和 Mozilla。但它不适用于有福的 IE,因为 IE 不会触发 onload 事件:它认为它已经处理了这个文件中的所有 onload,你不能让它做另一个。然而,IE 很乐意使用 JQuery getScript 函数加载文件(Chrome 不允许,因为 ccess-control-allow-origin 策略)——您将需要 JQuery 库才能工作。所以这就是我最终的结果:

function getMyText(){
    var url='mylocalfile.js';
    if (jQuery.support.scriptEval) { 
        var old = document.getElementById('uploadScript');  
        if (old != null) {  
             old.parentNode.removeChild(old);  
             delete old;  
            } 
        var head = document.getElementsByTagName("head")[0]; 
        var script = document.createElement('script');
        script.id = 'uploadScript';
        script.type = 'text/javascript';
        script.onload = refresh_page; 
        script.src = url; 
        head.appendChild(script);  
    } else {
       $.getScript(url,function(){
            refresh_page();
      });
     }
}

function refresh_page() {
    alert(mytext);
}

In all this, mylocaltext.js defines all my html as the content of a variable, mytext. Ugly, but it works. jQuery.support.scriptEval is true for intelligent browsers that fire onload events if the DOM changes. IE does not, so that sends it to .getScript; Chrome and others do, so that sends them the other way. Anyway this works on local files.

在所有这些中,mylocaltext.js 将我的所有 html 定义为变量 mytext 的内容。丑陋,但它的工作原理。jQuery.support.scriptEval 适用于智能浏览器,如果 DOM 更改,则触发 onload 事件。IE 没有,因此将其发送到 .getScript;Chrome 和其他人这样做,所以他们以另一种方式发送。无论如何,这适用于本地文件。

回答by peter

Interesting, but how can I use the same technique to load in a whole HTML file? Similar problem to yours -- I have hundreds of HTML files which I want to include within a web page, depending on what the user wants to see. It seems I can use this technique to load in a whole HTML page, something like:

有趣,但我如何使用相同的技术加载整个 HTML 文件?与您的问题类似——我有数百个 HTML 文件,我想将它们包含在网页中,具体取决于用户希望看到的内容。似乎我可以使用这种技术加载整个 HTML 页面,例如:

script.id = 'uploadScript';
script.type = 'text/html';
script.src = url; 
script.onload = refresh_page; 
head.appendChild(script);  

ie, tell it load in HTML. I can see from the console that it is loading it into the page, and I get a message 'Resource interpreted as script but transferred with MIME type text/html'. But I cannot figure out any way to get at the HTML loaded in and held within the script

即,告诉它在 HTML 中加载。我可以从控制台看到它正在将它加载到页面中,并且我收到一条消息“资源被解释为脚本但使用 MIME 类型文本/html 传输”。但是我想不出任何方法来获取脚本中加载和保存的 HTML