绕过本地文件系统上的 Chrome Access-control-allow-origin?
Posted
技术标签:
【中文标题】绕过本地文件系统上的 Chrome Access-control-allow-origin?【英文标题】:Circumventing Chrome Access-control-allow-origin on the local file system? 【发布时间】:2011-06-12 03:56:30 【问题描述】:我已经阅读了关于 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 帖子,但它们并未描述我遇到的问题:
Ways to circumvent the same-origin policyXMLHttpRequest Origin null is not allowed Access-Control-Allow-Origin for file:/// to file:/// (Serverless)Cross-site XMLHttpRequest
同样,我最后的手段是在网页加载时加载所有数据 - 这可能会导致加载网页时出现长达 10 秒的延迟,这对于 90% 的应用用户来说是不必要的。
感谢您的任何建议/替代方案!!!
【问题讨论】:
【参考方案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
【讨论】:
Peter,我认为您在尝试将 HTML 页面加载到 是的,我想通了。我可以将每个 html 文件(或至少 body 元素)的内容作为 c-point.com/javascript_tutorial/Editor/ajax_tutorial.htm 中解释的 javascript 函数的参数,加载包含在函数中的文件,然后将包含所有数据的参数传递给我要填充的元素的 innerHTML。这似乎是一种非常可怕的方法。或者,一个人可能会尝试 XMLHttpRequest 但我想这会遇到完全相同的访问控制允许来源问题。所以我认为唯一的方法是假装我的 html 实际上是一个参数。 果然,是的:XMLHttpRequest 给了我完全相同的错误。而且浏览器真的不喜欢为 javascript 函数获取如此可怕的参数。滋扰。数据量不是很大,但是很烦人。 我又来了。好的,它确实有效!必须这样做:源文件将整个 html 放入一个 javascript 变量中,var mytext=" etc etc"。麻烦的是,您必须确保 html 中没有 ",并且所有内容都必须在一行上。但是如果您这样做,那么您需要做的就是说 document.getElementById('mydiv').innerHTML =mytext 并且一切正常。在 Chrome、Mozilla 中。不了解 IE。但它应该可以正常工作。【参考方案2】:我认为我已经想通了。
我真正需要做的就是在我的<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 函数时遇到的访问控制允许来源策略。
【讨论】:
【参考方案3】:好吧,做了很多摆弄,浪费了很多时间。但我明白了。 我上一个答案中的解决方案适用于 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 和其他人这样做,因此以另一种方式发送它们。无论如何,这适用于本地文件。
【讨论】:
别那么快,伙计们。当您一次只加载一个文件时,这可以正常工作。如果您尝试一个接一个地加载多个文件,它在 IE 中不起作用——也就是说,您会遇到取决于您的服务器的同步问题。在本地主机上似乎没问题,但在远程服务器上存在不可预测的时间延迟,唯一的方法是至少在 IE 7 中加载多个文件时避免这样做。滋扰。以上是关于绕过本地文件系统上的 Chrome Access-control-allow-origin?的主要内容,如果未能解决你的问题,请参考以下文章