读取 IE XMLHttpRequest 中的 file:// URL
我正在开发一个 JavaScript 应用程序,该应用程序可以从 Web 服务器(通过 http)或文件系统(在 file:// URL 上)运行。
作为此代码的一部分,我需要使用 XMLHttpRequest 加载与页面相同的目录以及页面的子目录中的文件。
此代码在 Web 服务器上执行时工作正常(“PASS”),但在脱离文件系统运行时在 Internet Explorer 8 中不起作用(“FAIL”):
<html><head>
<script>
window.onload = function() {
var xhr = new XMLHttpRequest();
xhr.open("GET", window.location.href, false);
xhr.send(null);
if (/TestString/.test(xhr.responseText)) {
document.body.innerHTML="<p>PASS</p>";
}
}
</script>
<body><p>FAIL</p></body>
当然,一开始它会失败,因为没有脚本可以运行全部在文件系统上;系统会向用户提示黄色条,警告“为了帮助保护您的安全,Internet Explorer 已限制此网页运行可以访问您的计算机的脚本或 ActiveX 控件”。
但即使我单击该栏并“允许阻止的内容”,该页面仍然失败;我在 xhr.open 调用中收到“访问被拒绝”错误。
这让我很困惑,因为 MSDN 表示“出于开发目的,本地计算机区域允许使用 file:// 协议。”这个本地文件应该是本地计算机区域的一部分,对吧?
我怎样才能让这样的代码工作?我可以用安全警告提示用户;我不同意强迫他们关闭控制面板中的安全功能。
编辑:事实上,在我的例子中,我并没有加载 XML 文档;我正在加载纯文本文件 (.txt)。
I'm developing a JavaScript application that's meant to be run either from a web server (over http) or from the file system (on a file:// URL).
As part of this code, I need to use XMLHttpRequest to load files in the same directory as the page and in subdirectories of the page.
This code works fine ("PASS") when executed on a web server, but doesn't work ("FAIL") in Internet Explorer 8 when run off the file system:
<html><head>
<script>
window.onload = function() {
var xhr = new XMLHttpRequest();
xhr.open("GET", window.location.href, false);
xhr.send(null);
if (/TestString/.test(xhr.responseText)) {
document.body.innerHTML="<p>PASS</p>";
}
}
</script>
<body><p>FAIL</p></body>
Of course, at first it fails because no scripts can run at all on the file system; the user is prompted a yellow bar, warning that "To help protect your security, Internet Explorer has restricted this webpage from running scripts or ActiveX controls that could access your computer."
But even once I click on the bar and "Allow Blocked Content" the page still fails; I get an "Access is Denied" error on the xhr.open call.
This puzzles me, because MSDN says that "For development purposes, the file:// protocol is allowed from the Local Machine zone." This local file should be part of the Local Machine Zone, right?
How can I get code like this to work? I'm fine with prompting the user with security warnings; I'm not OK with forcing them to turn off security in the control panel.
EDIT: I am not, in fact, loading an XML document in my case; I'm loading a plain text file (.txt).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
嗯,这可能是本机 XMLHttpRequest 对象和 ActiveX 对象之间的区别吗?我似乎还记得一些关于那件事的事情。也就是说,不要
尝试
“显而易见”,而是进行一些检查来查看浏览器是否支持 ActiveX。当然,这也仅限于 IE。
Hmm, could it be the difference between the native XMLHttpRequest object and the ActiveX one? I seem to remember something about that. That is, instead of
try
Obviously, put some checks in place to see if the browser supports ActiveX. Of course, this is limited to IE only, as well.
正如上面所建议的,这看起来像是 Microsoft XMLHttpRequest 中的错误。 jQuery(2011 年 7 月)还写道:-
我也确认了 IE8 的此失败。
如果
XMLHttpRequest
不起作用,解决方案是对本地文件使用new window.ActiveXObject( "Microsoft.XMLHTTP" )
。失败发生在
xhr.open
行中,因此可以在那里捕获它,然后尝试ActiveXObject
,如下所示:-此代码至少将使用标准
XMLHttpRequest。对于上面的
jQuery
代码,只要ActiveXObject
可用,就会使用非标准的Microsoft.XMLHTTP
,即使 Microsoft 修复了错误。As suggested above, this looks like a fault in
Microsoft XMLHttpRequest
. jQuery (Jul 2011) also writes:-I confirm this failure for IE8 too.
A solution is to use
new window.ActiveXObject( "Microsoft.XMLHTTP" )
for local files ifXMLHttpRequest
doesn't work.The failure is in the
xhr.open
line so it can be caught there and then tryActiveXObject
as follows:-This code will at least use standard
XMLHttpRequest
for IE9 (untested) and future IE browsers if/when Microsoft fixes the fault. With thejQuery
code above, non standardMicrosoft.XMLHTTP
will be used wheneverActiveXObject
is available, even if Microsoft fix the fault.我只是偶然发现了完全相同的问题。如上所述,非本机 ActiveX“构造函数”可以工作。我不太确定这两个对象是否应用了不同的策略,但由于 jQuery 也提到了同样的问题,这可能是一个真正的错误。以下是 jQuery 源代码中的相关代码(1.4.2,第 4948 行):
I just happened to stumble across exactly the same problem. As suggested above, the non-native ActiveX "constructor" works. I’m not really sure whether there are different policies applied to the two objects, but since jQuery mentions the same problem as well, it may be a genuine bug. Here is the relevant piece of code from the jQuery source (1.4.2, line 4948):
我知道这已经过时了 - 但想用更多细节来澄清正在发生的事情,并提供一些潜在的选择。
首先,这实际上不是 IE 中的缺陷,而是 Chrome 中也存在的安全功能。
基本上,任何带有 file:// 前缀的资源 URI 都不允许使用 XMLHttpRequest 加载任何其他带有 file:// 前缀的资源 URI。
在 IE 中,您将看到“拒绝访问”消息。在 Chrome 中,您将看到“无法加载资源:Access-Control-Allow-Origin 不允许 Origin null”
更多信息-> 有关 IE 的信息 和 有关 Chrome 的信息(查找 --allow-file-access-from-files)
我知道有几种解决方法 - 没有一个是理想的,因为它们禁用了
再次强调,这是浏览器中的一项安全功能,旨在减轻潜在的威胁向量 - 类似于跨域脚本块。
I know this is old - but wanted to clarify what is going on with a little more detail, and offer a couple of potential options.
First off this is actually not a flaw within IE, but a security feature that exists in Chrome as well.
Basically, any resource URI with file:// prefix is not allowed to load any other resource URI with file:// prefix using XMLHttpRequest.
In IE you will see an Access Denied message. In Chrome you will see "Failed to load resource: Origin null is not allowed by Access-Control-Allow-Origin"
More info -> Information on IE and Information on Chrome (look for --allow-file-access-from-files)
There are a couple of workarounds that I am aware of - none of which are ideal, as they disable a measure of security protection
Once again, this is a security feature within browsers to mitigate potential threat vectors - similar to the Cross Domain scripting blocks.
请尝试此页面。我通过以下方式解决了问题:
通过终端在工作区目录/home/user/web_ws中启动http服务器:
python -m SimpleHTTPServer
它开始在 0.0.0.0 端口 8000 上提供 HTTP 服务...,并带有一些 GET 请求。
然后我在浏览器中使用网址
http: 加载了我的网页(名为 check.html): //localhost:8000/check.html
。因此,我的 file:///home/user/web_ws/ 已转换为 http://localhost:8000/)。
接下来是通过源选项卡(从检查器坞)设置我的工作区。我刚刚将工作区文件夹添加到源工作区,之后一切正常。
Try this page. I resolved the problem by:
Starting an http server in the workspace directory /home/user/web_ws through terminal:
python -m SimpleHTTPServer
It started Serving HTTP on 0.0.0.0 port 8000 ... with some GET requests..
Then I loaded my web page (named check.html) in browser with web-address
http://localhost:8000/check.html
.So, my file:///home/user/web_ws/ was converted to http://localhost:8000/).
Next thing was to set-up my workspace through Sources tab (from the Inspector dock). I just added my Workspace folder to the Sources workspace and all worked fine after that.