Читать файл://URL-адреса в IE XMLHttpRequest

Я разрабатываю приложение JavaScript, предназначенное для запуска либо с веб-сервера (через http), либо из файловой системы (в файле://URL).

В качестве части этого кода мне нужно использовать XMLHttpRequest для загрузки файлов в том же каталоге, что и страница и в подкаталоги страницы.

Этот код отлично работает ( "PASS" ) при выполнении на веб-сервере, но не работает ( "FAIL" ) в 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>

Конечно, сначала это терпит неудачу, потому что никакие скрипты вообще не могут запускаться в файловой системе; пользователю предлагается желтая полоса, предупреждая, что "Чтобы защитить вашу безопасность, Internet Explorer ограничил эту веб-страницу запуском скриптов или элементов ActiveX, которые могли бы получить доступ к вашему компьютеру".

Но даже когда я нажимаю на панель и "Разрешить заблокированный контент", страница все еще не работает; Я получаю сообщение "Доступ отрицается" при вызове xhr.open.

Это меня озадачивает, потому что MSDN говорит, что "Для целей разработки протокол file://разрешено в зоне локального компьютера." Этот локальный файл должен быть частью зоны локального компьютера, правильно?

Как я могу заставить код работать так? Я в порядке, предлагая пользователю предупреждения о безопасности; Я не в порядке, заставляя их отключать безопасность на панели управления.

EDIT: Я действительно не загружаю XML-документ в моем случае; Я загружаю простой текстовый файл (.txt).

Ответ 1

Хм, это может быть разница между собственным объектом XMLHttpRequest и ActiveX? Кажется, я что-то помню об этом. То есть вместо

var xhr = new XMLHttpRequest();

попробуйте

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

Очевидно, поместите некоторые проверки, чтобы проверить, поддерживает ли браузер ActiveX. Конечно, это ограничивается только IE.

Ответ 2

Я просто случайно наткнулся на ту же проблему. Как было предложено выше, работает не-native 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) {}
    }

Ответ 3

Как я могу заставить код работать так?

Как указано выше, это выглядит как ошибка в Microsoft XMLHttpRequest. jQuery (июль 2011) также пишет: -

Microsoft не смогла должным образом реализовать XMLHttpRequest в IE7 (не может запрашивать локальные файлы)

Я подтверждаю эту ошибку и для 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)
    }
}

Этот код, по крайней мере, будет использовать стандартный XMLHttpRequest для IE9 (untested) и будущих браузеров IE, если/когда Microsoft исправляет ошибку. С приведенным выше кодом jQuery нестандартный Microsoft.XMLHTTP будет использоваться всякий раз, когда ActiveXObject доступен, даже если Microsoft исправит ошибку.