12

我正在开发一个 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)。

4

5 回答 5

8

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

var xhr = new XMLHttpRequest();

尝试

var xhr = new ActiveXObject("MSXML2.XMLHTTP");

显然,进行一些检查以查看浏览器是否支持 ActiveX。当然,这也仅限于 IE。

于 2010-01-26T20:04:17.707 回答
8

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

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

微软在 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)
    }
}

如果/当微软修复错误时,此代码将至少使用XMLHttpRequestIE9(未经测试)和未来 IE 浏览器的标准。使用上面的代码,即使微软修复了错误,只要可用,就会使用jQuery非标准。Microsoft.XMLHTTPActiveXObject

于 2011-07-31T07:05:33.330 回答
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) {}
    }
于 2010-05-02T10:37:19.117 回答
1

我知道这已经过时了——但想用更多细节来澄清发生了什么,并提供一些潜在的选择。

首先,这实际上不是IE 中的缺陷,而是 Chrome 中存在的安全功能。

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

在 IE 中,您将看到拒绝访问消息。在 Chrome 中,您将看到“加载资源失败:Access-Control-Allow-Origin 不允许 Origin null”更多信息 -> IE上的信息和Chrome上的信息(查找 --allow-file-access-from-files )

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

我知道有几种解决方法 - 没有一个是理想的,因为它们禁用了某种安全保护措施

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

再一次,这是浏览器中的一项安全功能,用于减轻潜在的威胁向量 - 类似于跨域脚本块。

于 2018-07-13T16:32:19.863 回答
0

试试这个页面。我通过以下方式解决了问题:

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

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

  3. 接下来是通过Sources选项卡(来自Inspector Dock)设置我的工作区。我刚刚将我的 Workspace 文件夹添加到 Sources 工作区,之后一切正常。

- Himanshu

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

于 2020-12-26T02:04:13.133 回答