Прочитать файл: // URL в IE XMLHttpRequest - PullRequest
12 голосов
/ 26 января 2010

Я разрабатываю приложение 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: // разрешен из зоны локального компьютера». Этот локальный файл должен быть частью зоны локального компьютера, верно?

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

РЕДАКТИРОВАТЬ: На самом деле я не загружаю документ XML в моем случае; Я загружаю простой текстовый файл (.txt).

Ответы [ 4 ]

8 голосов
/ 26 января 2010

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

var xhr = new XMLHttpRequest();

попробуй

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

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

7 голосов
/ 31 июля 2011

Как мне заставить этот код работать?

Как указано выше, это похоже на ошибку в 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 (не проверено) и будущих браузеров IE, если / когда Microsoft исправит ошибку. С кодом jQuery, указанным выше, нестандартный Microsoft.XMLHTTP будет использоваться всякий раз, когда доступен ActiveXObject, даже если Microsoft исправит ошибку.

7 голосов
/ 02 мая 2010

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

Я знаю, что это старое - но хотел уточнить, что происходит, с более подробной информацией и предложить пару потенциальных вариантов.

Прежде всего, это на самом деле не недостаток в IE, но функция безопасности, которая существует и в Chrome.

В принципе, любой URI ресурса с префиксом file: // не может загружать любой другой URI ресурса с префиксом file: // с использованием XMLHttpRequest.

В IE вы увидите сообщение «Отказано в доступе». В Chrome вы увидите «Не удалось загрузить ресурс: нулевой источник не разрешен Access-Control-Allow-Origin» Подробнее -> Информация о IE и Информация о Chrome (ищите --allow-file-access-from-files)

Интересной особенностью IE является то, что если вы используете .NET Browser Контроль внутри приложения WinForm или Silverlight, эта функция отключен, и у вас не будет тех же проблем.

Есть несколько обходных путей, о которых я знаю, но ни один из них не идеален, поскольку они отключают меры защиты безопасности

  • IE: первое и самое «мягкое» - это то, что вы можете добавить URI вызывающей страницы в зону надежных сайтов (снимите флажок «Включить защищенный режим»)
  • IE: по ссылке выше есть параметр реестра, который вы можете изменить, чтобы отключить эту функцию - но это должно быть сделано на каждой машине, пытающейся загрузить ресурсы
  • Chrome: ссылка выше относится к использованию переключателя командной строки при запуске Chrome для отключения этой функции.

Еще раз, это функция безопасности в браузерах для снижения потенциальных векторов угроз - аналогично междоменным блокам сценариев.

...