在IE XMLHttpRequest中读取file:// URL

时间:2010-01-26 19:52:39

标签: ajax security file internet-explorer 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>

当然,首先它失败了,因为文件系统上根本没有脚本可以运行;系统会提示用户出现黄色条,警告“为了保护您的安全,Internet Explorer已限制此网页运行可以访问您计算机的脚本或ActiveX控件。”

但即使我点击栏并“允许阻止的内容”,页面仍然会失败;我在xhr.open调用中遇到“Access is Denied”错误。

这让我很困惑,因为MSDN说“出于开发目的,允许从本地计算机区域使用file://协议。”这个本地文件应该是Local Machine Zone的一部分,对吗?

我如何才能获得这样的代码?我很好地提示用户提供安全警告;我不能强迫他们关闭控制面板中的安全性。

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

5 个答案:

答案 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 IEInformation on Chrome(查找--allow-file-access-from-files)

  

IE的有趣之处在于,如果您使用的是.NET浏览器   在WinForm或Silverlight应用程序内部进行控制,此功能是   禁用,您将不会遇到相同的问题。

我知道有两种解决方法-都不是理想的选择,因为它们禁用了一定的安全保护措施

  • IE:第一个也是最“良性的”是,您可以将调用页面的URI添加到“受信任的站点”区域中(取消选中“启用保护模式”)
  • IE:在上面的链接之后,您可以修改注册表设置,该设置将禁用此功能-但这必须在尝试加载资源的每台计算机上完成
  • Chrome:上面的链接是指在启动Chrome禁用此功能时使用命令行开关。

再次,这是浏览器中的安全功能,用于缓解潜在的威胁源-与跨域脚本块类似。

答案 4 :(得分:0)

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

  1. 通过终端在工作区目录/home/user/web_ws中启动一个http服务器:
    python -m SimpleHTTPServer
    它启动了服务HTTP在 0.0.0.0 端口 8000 ... 上有一些 GET 请求...

  2. 然后我在浏览器中加载了我的网页(名为 check.html),网址为 http://localhost:8000/check.html
    所以,我的file:///home/user/web_ws/被转换为http://localhost:8000/)。

  3. 接下来是通过 Sources 标签(从 Inspector 停靠栏)设置我的工作区。我刚刚将我的 Workspace 文件夹添加到 Sources 工作区,之后一切正常。

-喜满树

(我不是网络开发人员,只是对 html、xml、css、js 等有一点了解,并且碰巧尝试了我的一个使用 xml 文件的项目的理智。如果我是不正确的地方,做评论,很高兴学习;-)