我正在开发一个JavaScript应用程序,该应用程序可以从Web服务器(通过http)或从文件系统(在文件:// 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调用中遇到“Access is Denied”错误。
这让我很困惑,因为MSDN说“出于开发目的,允许从本地计算机区域使用file://协议。”这个本地文件应该是Local Machine Zone的一部分,对吗?
我如何才能获得这样的代码?我很好地提示用户提供安全警告;我不能强迫他们关闭控制面板中的安全性。
编辑:事实上,我不是在我的案例中加载XML文档;我正在加载纯文本文件(.txt)。
答案 0 :(得分:8)
嗯,它可能是原生XMLHttpRequest对象和ActiveX对象之间的区别吗?我似乎记得那件事。也就是说,而不是
var xhr = new XMLHttpRequest();
尝试
var xhr = new ActiveXObject("MSXML2.XMLHTTP");
显然,做一些检查以确定浏览器是否支持ActiveX。当然,这仅限于IE。
答案 1 :(得分:7)
我碰巧遇到了完全相同的问题。如上所述,非本机ActiveX“构造函数”有效。我不确定是否有不同的策略应用于这两个对象,但由于jQuery也提到同样的问题,它可能是一个真正的错误。以下是jQuery源代码中的相关代码段(1.4.2,第4948行):
// Create the request object; Microsoft failed to properly
// implement the XMLHttpRequest in IE7 (can't request local files),
// so we use the ActiveXObject when it is available
// This function can be overriden by calling jQuery.ajaxSetup
xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
function() {
return new window.XMLHttpRequest();
} :
function() {
try {
return new window.ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {}
}
答案 2 :(得分:7)
我如何才能获得这样的代码?
如上所述,这看起来像Microsoft XMLHttpRequest
中的错误。 jQuery(2011年7月)也写道: -
Microsoft未能在IE7中正确实现XMLHttpRequest(无法请求本地文件)
我也确认了IE8的失败。
如果new window.ActiveXObject( "Microsoft.XMLHTTP" )
不起作用,解决方案是将XMLHttpRequest
用于本地文件。
失败位于xhr.open
行,因此可以将其捕获,然后尝试ActiveXObject
,如下所示: -
var xhr = new XMLHttpRequest()
try {
xhr.open('GET', url, true)
}
catch(e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
xhr.open('GET', url, true)
}
catch (e1) {
throw new Error("Exception during GET request: " + e1)
}
}
如果/当Microsoft修复错误时,此代码至少会对IE9(未经测试)和未来的IE浏览器使用标准XMLHttpRequest
。使用上面的jQuery
代码,只要Microsoft.XMLHTTP
可用,就会使用非标准ActiveXObject
,即使Microsoft修复了错误。
答案 3 :(得分:1)
我知道这很古老-但想更详细地说明正在发生的事情,并提供一些潜在的选择。
首先,这实际上不是IE中的缺陷,而是Chrome中也存在的安全功能。
基本上,任何带有file://前缀的资源URI都不允许使用XMLHttpRequest加载任何带有file://前缀的资源URI。
在IE中,您将看到“访问被拒绝”消息。在Chrome中,您将看到“无法加载资源:Access-Control-Allow-Origin不允许使用原产null” 更多信息-> Information on IE和Information on Chrome(查找--allow-file-access-from-files)
IE的有趣之处在于,如果您使用的是.NET浏览器 在WinForm或Silverlight应用程序内部进行控制,此功能是 禁用,您将不会遇到相同的问题。
我知道有两种解决方法-都不是理想的选择,因为它们禁用了一定的安全保护措施
再次,这是浏览器中的安全功能,用于缓解潜在的威胁源-与跨域脚本块类似。
答案 4 :(得分:0)
试试this page。我通过以下方式解决了问题:
通过终端在工作区目录/home/user/web_ws中启动一个http服务器:python -m SimpleHTTPServer
它启动了服务HTTP在 0.0.0.0 端口 8000 ... 上有一些 GET 请求...
然后我在浏览器中加载了我的网页(名为 check.html),网址为 http://localhost:8000/check.html
。
所以,我的file:///home/user/web_ws/被转换为http://localhost:8000/)。
接下来是通过 Sources 标签(从 Inspector 停靠栏)设置我的工作区。我刚刚将我的 Workspace 文件夹添加到 Sources 工作区,之后一切正常。
-喜满树
(我不是网络开发人员,只是对 html、xml、css、js 等有一点了解,并且碰巧尝试了我的一个使用 xml 文件的项目的理智。如果我是不正确的地方,做评论,很高兴学习;-)