Dan*_*ich 12 security ajax internet-explorer file file-uri
我正在开发一个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>
Run Code Online (Sandbox Code Playgroud)
当然,起初它失败了,因为文件系统上根本没有脚本可以运行; 用户会被提示一个黄色条,警告"为了帮助保护您的安全,Internet Explorer已限制此网页运行可以访问您的计算机的脚本或ActiveX控件."
但即使我点击栏和"允许被阻止的内容",页面仍然会失败; 我在xhr.open调用中遇到"Access is Denied"错误.
这让我很困惑,因为MSDN说"出于开发目的,允许从本地计算机区域使用file://协议." 这个本地文件应该是Local Machine Zone的一部分,对吧?
我怎样才能获得这样的代码?我很好地提示用户提供安全警告; 我不能强迫他们关闭控制面板中的安全性.
编辑:事实上,我不是在我的情况下加载XML文档; 我正在加载纯文本文件(.txt).
嗯,它可能是原生XMLHttpRequest对象和ActiveX之间的区别吗?我似乎记得那件事.也就是说,而不是
var xhr = new XMLHttpRequest();
Run Code Online (Sandbox Code Playgroud)
尝试
var xhr = new ActiveXObject("MSXML2.XMLHTTP");
Run Code Online (Sandbox Code Playgroud)
显然,做一些检查以确定浏览器是否支持ActiveX.当然,这仅限于IE.
小智 8
我怎样才能获得这样的代码?
如上所述,这看起来像是一个错误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)
}
}
Run Code Online (Sandbox Code Playgroud)
XMLHttpRequest
如果/当Microsoft修复故障时,此代码至少会使用IE9(未经测试)和未来IE浏览器的标准.使用jQuery
上面的代码,即使Microsoft修复了错误,也会在可用Microsoft.XMLHTTP
时使用非标准ActiveXObject
.
我碰巧遇到了完全相同的问题.如上所述,非本机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) {}
}
Run Code Online (Sandbox Code Playgroud)