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

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

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

5 ответов

Решение

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

var xhr = new XMLHttpRequest();

пытаться

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

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

Как я могу получить такой код для работы?

Как указано выше, это выглядит как ошибка в 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 исправит ошибку.

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

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

Во-первых, это на самом деле не изъян в IE, а функция безопасности, существующая и в Chrome.

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

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

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

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

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

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

Попробуйте эту страницу . Я решил проблему:

  1. Запуск http-сервера в каталоге рабочей области /home/user/web_ws через терминал:
    python -m SimpleHTTPServer
    Он начал обслуживать HTTP на порту 0.0.0.0 8000... с некоторыми запросами GET .

  2. Затем я загрузил свою веб-страницу (с именем check.html) в браузере с веб-адресом http://localhost:8000/check.html.
    Итак, мой файл:///home/user/web_ws/ был преобразован в http://localhost:8000/ ).

  3. Следующим шагом было настроить мое рабочее пространство через вкладку « Источники » (из дока « Инспектор »). Я просто добавил папку «Рабочая область» в рабочую область «Источники», и после этого все заработало нормально.

- Химаншу

(Я не веб-разработчик, просто имею небольшое представление о html, xml, css, js и т. д., и просто случайно попробовал вменяемость моего проекта, который использует файлы xml. Если я где-то не прав , комментируйте, рад узнать ;-)

Другие вопросы по тегам