Ajax 读取IE XMLHttpRequest中的文件://URL

Ajax 读取IE XMLHttpRequest中的文件://URL,ajax,security,file,internet-explorer,file-uri,Ajax,Security,File,Internet Explorer,File Uri,我正在开发一个JavaScript应用程序,该应用程序可以从web服务器(通过http)或文件系统(通过文件://URL)运行 作为这段代码的一部分,我需要使用XMLHttpRequest在页面所在的目录和页面的子目录中加载文件 此代码在web服务器上执行时工作正常(“通过”),但在Internet Explorer 8中从文件系统运行时不工作(“失败”): <html><head> <script> window.onload = function() {

我正在开发一个JavaScript应用程序,该应用程序可以从web服务器(通过http)或文件系统(通过文件://URL)运行

作为这段代码的一部分,我需要使用XMLHttpRequest在页面所在的目录和页面的子目录中加载文件

此代码在web服务器上执行时工作正常(“通过”),但在Internet Explorer 8中从文件系统运行时不工作(“失败”):

<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>

window.onload=函数(){
var xhr=new XMLHttpRequest();
xhr.open(“GET”,window.location.href,false);
xhr.send(空);
if(/TestString/.test(xhr.responseText)){
document.body.innerHTML=“PASS

”; } } 失败

当然,一开始它失败了,因为没有脚本可以在文件系统上运行;用户将收到一个黄色条提示,警告“为了帮助保护您的安全,Internet Explorer已限制此网页运行可访问您的计算机的脚本或ActiveX控件。”

但即使我点击了工具栏并“允许阻止内容”,页面仍然失败;我在xhr.open调用中遇到“访问被拒绝”错误

这让我感到困惑,因为上面说“出于开发目的,允许本地机器区域使用文件://协议。”这个本地文件应该是本地机器区域的一部分,对吗

我怎样才能让这样的代码工作?我可以用安全警告提示用户;我不同意强迫他们关闭控制面板的安全


编辑:事实上,我并没有在我的案例中加载XML文档;我正在加载一个纯文本文件(.txt)。

嗯,这可能是原生XMLHttpRequest对象和ActiveX对象之间的区别吗?我似乎还记得那件事。也就是说,而不是

var xhr = new XMLHttpRequest();
试一试


显然,要检查浏览器是否支持ActiveX。当然,这也仅限于IE。

我碰巧遇到了完全相同的问题。如上所述,非本机ActiveX“构造函数”可以工作。我不确定这两个对象是否应用了不同的策略,但由于jQuery也提到了相同的问题,这可能是一个真正的bug。以下是jQuery源代码中的相关代码(1.4.2,第4948行):

我怎样才能让这样的代码工作

如上所述,这看起来像是Microsoft XMLHttpRequest中的故障。jQuery(2011年7月)还写道:-

Microsoft未能在IE7中正确实现XMLHttpRequest(无法请求本地文件)

我也确认IE8的失败

如果
XMLHttpRequest
不起作用,解决方案是对本地文件使用
newwindow.ActiveXObject(“Microsoft.XMLHTTP”)

故障出现在
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
代码,只要
ActiveXObject
可用,即使Microsoft修复了故障,也将使用非标准的
Microsoft.XMLHTTP

我知道这是一个老问题,但我想更详细地说明问题所在,并提供一些可能的选项

首先,这实际上不是IE中的一个缺陷,而是Chrome中存在的一个安全特性

基本上,任何具有file://前缀的资源URI都不允许使用XMLHttpRequest加载具有file://前缀的任何其他资源URI

在IE中,您将看到一条拒绝访问的消息。在Chrome中,您将看到“加载资源失败:访问控制不允许原点为null允许原点” 更多信息->和(查找--允许从文件访问文件)

IE的一个有趣之处是,如果您使用的是.NET浏览器 控件在WinForm或Silverlight应用程序中,此功能是 禁用,您将不会遇到相同的问题

据我所知,有两种变通方法——没有一种是理想的,因为它们禁用了安全保护措施

  • IE:第一个,也是最“良性的”,是您可以将调用页面的URI添加到受信任的站点区域(取消选中“启用受保护模式”)
  • IE:在上面的链接之后,有一个注册表设置,您可以修改它,它将禁用此功能,但这必须在试图加载资源的每台机器上完成
  • Chrome:上面的链接是指在启动Chrome时使用命令行开关来禁用该功能
再一次,这是浏览器中的一个安全功能,用于缓解潜在的威胁向量-类似于跨域脚本块

试试看。我通过以下方式解决了问题:

  • 通过终端启动工作区目录/home/user/web\ws中的http服务器:
    python-m SimpleHTTPServer

    它启动了在0.0.0.0端口8000上提供http…,并发出了一些GET请求

  • 然后我在浏览器中加载了我的网页(名为check.html),网址为
    http://localhost:8000/check.html

    那么,我的file:///home/user/web_ws/ 改为http://localhost:8000/)

  • 下一件事是通过选项卡(从检查器驳接)设置我的工作区。我刚刚将我的工作区文件夹添加到源代码工作区,之后一切正常

  • -希曼苏


    (我不是一名web开发人员,只是对html、xml、css、js等有一点了解,只是碰巧尝试了我的一个使用xml文件的项目。如果我在某个地方不正确,请发表评论,很高兴了解;-)

    您是否尝试过var xhr=new ActiveXObject(“MSXML2.XMLHTTP”);(见下面我的答案)?这不应该局限于XML文件。但这将是有限的
    // 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) {}
        }
    
    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)
        }
    }