读取 IE XMLHttpRequest 中的 file:// URL

发布于 2024-08-19 10:04:26 字数 1113 浏览 8 评论 0原文

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

I'm developing a JavaScript application that's meant to be run either from a web server (over http) or from the file system (on a file:// URL).

As part of this code, I need to use XMLHttpRequest to load files in the same directory as the page and in subdirectories of the page.

This code works fine ("PASS") when executed on a web server, but doesn't work ("FAIL") in Internet Explorer 8 when run off the file system:

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

Of course, at first it fails because no scripts can run at all on the file system; the user is prompted a yellow bar, warning that "To help protect your security, Internet Explorer has restricted this webpage from running scripts or ActiveX controls that could access your computer."

But even once I click on the bar and "Allow Blocked Content" the page still fails; I get an "Access is Denied" error on the xhr.open call.

This puzzles me, because MSDN says that "For development purposes, the file:// protocol is allowed from the Local Machine zone." This local file should be part of the Local Machine Zone, right?

How can I get code like this to work? I'm fine with prompting the user with security warnings; I'm not OK with forcing them to turn off security in the control panel.

EDIT: I am not, in fact, loading an XML document in my case; I'm loading a plain text file (.txt).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无名指的心愿 2024-08-26 10:04:26

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

var xhr = new XMLHttpRequest();

尝试

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

“显而易见”,而是进行一些检查来查看浏览器是否支持 ActiveX。当然,这也仅限于 IE。

Hmm, could it be the difference between the native XMLHttpRequest object and the ActiveX one? I seem to remember something about that. That is, instead of

var xhr = new XMLHttpRequest();

try

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

Obviously, put some checks in place to see if the browser supports ActiveX. Of course, this is limited to IE only, as well.

青巷忧颜 2024-08-26 10:04:26

如何让这样的代码工作?

正如上面所建议的,这看起来像是 Microsoft XMLHttpRequest 中的错误。 jQuery(2011 年 7 月)还写道:-

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

我也确认了 IE8 的此失败。

如果 XMLHttpRequest 不起作用,解决方案是对本地文件使用 new window.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)
    }
}

此代码至少将使用标准 XMLHttpRequest。对于上面的 jQuery 代码,只要 ActiveXObject 可用,就会使用非标准的 Microsoft.XMLHTTP,即使 Microsoft 修复了错误。

How can I get code like this to work?

As suggested above, this looks like a fault in Microsoft XMLHttpRequest. jQuery (Jul 2011) also writes:-

Microsoft failed to properly implement the XMLHttpRequest in IE7 (can't request local files)

I confirm this failure for IE8 too.

A solution is to use new window.ActiveXObject( "Microsoft.XMLHTTP" ) for local files if XMLHttpRequest doesn't work.

The failure is in the xhr.open line so it can be caught there and then try ActiveXObject as follows:-

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

This code will at least use standard XMLHttpRequest for IE9 (untested) and future IE browsers if/when Microsoft fixes the fault. With the jQuery code above, non standard Microsoft.XMLHTTP will be used whenever ActiveXObject is available, even if Microsoft fix the fault.

日记撕了你也走了 2024-08-26 10:04:26

我只是偶然发现了完全相同的问题。如上所述,非本机 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) {}
    }

I just happened to stumble across exactly the same problem. As suggested above, the non-native ActiveX "constructor" works. I’m not really sure whether there are different policies applied to the two objects, but since jQuery mentions the same problem as well, it may be a genuine bug. Here is the relevant piece of code from the jQuery source (1.4.2, line 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) {}
    }
于我来说 2024-08-26 10:04:26

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

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

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

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

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

我知道有几种解决方法 - 没有一个是理想的,因为它们禁用了

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

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

I know this is old - but wanted to clarify what is going on with a little more detail, and offer a couple of potential options.

First off this is actually not a flaw within IE, but a security feature that exists in Chrome as well.

Basically, any resource URI with file:// prefix is not allowed to load any other resource URI with file:// prefix using XMLHttpRequest.

In IE you will see an Access Denied message. In Chrome you will see "Failed to load resource: Origin null is not allowed by Access-Control-Allow-Origin"
More info -> Information on IE and Information on Chrome (look for --allow-file-access-from-files)

An interesting thing with IE is that if you are using the .NET Browser
Control inside of a WinForm or Silverlight App, this feature is
disabled, and you will not have the same issues.

There are a couple of workarounds that I am aware of - none of which are ideal, as they disable a measure of security protection

  • IE: The first, and most "benign", is that you can add the URI of the calling page to the Trusted Sites zone (Uncheck "Enable Protected Mode")
  • IE: following the link above there is a registry setting that you can modify which will disable this feature - but this would have to be done on each machine trying to load the resources
  • Chrome: The link above refers to using the command line switch when starting Chrome to disable the feature.

Once again, this is a security feature within browsers to mitigate potential threat vectors - similar to the Cross Domain scripting blocks.

烟酒忠诚 2024-08-26 10:04:26

请尝试此页面。我通过以下方式解决了问题:

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

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

    因此,我的 file:///home/user/web_ws/ 已转换为 http://localhost:8000/)。

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

Try this page. I resolved the problem by:

  1. Starting an http server in the workspace directory /home/user/web_ws through terminal:
    python -m SimpleHTTPServer
    It started Serving HTTP on 0.0.0.0 port 8000 ... with some GET requests..

  2. Then I loaded my web page (named check.html) in browser with web-address http://localhost:8000/check.html.

    So, my file:///home/user/web_ws/ was converted to http://localhost:8000/).

  3. Next thing was to set-up my workspace through Sources tab (from the Inspector dock). I just added my Workspace folder to the Sources workspace and all worked fine after that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文