28

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

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

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

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

$.getScript("test.js");

这在 IE 和 Firefox 中运行良好。

在阅读了一堆关于此的内容后,我决定尝试直接写入文档的头部。在 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);

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

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

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

规避同源策略的方法
XMLHttpRequest Origin null is not allowed Access-Control-Allow-Origin for file:/// to file:///(无服务器)
跨站 XMLHttpRequest

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

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

4

3 回答 3

4

我已经想通了。

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

我有一个名为 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.  
}  

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

于 2011-01-20T18:38:00.703 回答
2

好吧,做了很多摆弄,浪费了很多时间。但我明白了。我上一个答案中的解决方案适用于 Chrome 和 Mozilla。但它不适用于受祝福的 IE,因为 IE 不会触发 onload 事件:它认为它已经处理了这个文件中的所有 onload,你不能让它再做另一个。然而,IE 很乐意使用 JQuery getScript 函数加载文件(由于 ccess-control-allow-origin 策略,Chrome 不允许使用该函数)——您需要 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);
}

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

于 2011-01-25T14:58:07.767 回答
1

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

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

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

于 2011-01-25T00:05:16.467 回答