Обход Chrome Access-control-allow-origin в локальной файловой системе? - PullRequest
28 голосов
/ 20 января 2011

Я читал другие те же темы политики происхождения здесь, в SO, но я не видел никаких решений, связанных с локальной файловой системой.

У меня есть веб-приложение (в широком смыслесловом) это должно быть местное служение.Я пытаюсь загрузить большой объем данных после того, как пользователь загрузил страницу, в зависимости от того, что они делают на веб-странице.В Firefox 3.5 и IE8 я могу использовать для этого методы AJAX () и GetScript () jQuery, но в Chrome это не удается из-за единой политики происхождения.

XMLHttpRequest не может загрузить file://test/testdir/test.js.Происхождение null не разрешено by Access-Control-Allow-Origin.

Это происходит, когда я делаю что-то простое, например

$.getScript("test.js");

Это прекрасно работает в IE и Firefox.

Прочитав кучу об этом, я решил попробовать написать прямо в заголовок документа.В консоли в Chrome я набрал следующее:

var head = document.getElementsByTagName("head")[0];  
var script =document.createElement('script');   
script.id = 'uploadScript';  
script.type = 'text/javascript';  
script.src = "upload.js";   
head.appendChild(script);

Это прекрасно работает при вставке в консоль - элемент <script...test.js</script> добавляется в заголовок, оценивается и содержимое загружается в DOM.

Я думал, что это успешно, пока я не вставил этот код в вызов функции.Тот же самый точный код, когда вызывается из функции, добавляет элемент к, но не оценивает файл JavaScript.Я не могу понять, почему.Если я использую консоль Chrome, чтобы остановить выполнение в методе, которым он добавляет элемент, и запустить приведенный выше код, он не оценивает его.Однако, если я приостановил выполнение и запустил точно такой же код (вставив его в окно консоли), это сработало.Я затрудняюсь объяснить это.Кто-нибудь имел дело с этим раньше?

Я прочитал следующие SO сообщения, но они не описывают мою проблему:

Способы обойти то же самоеПолитика происхождения
XMLHttpRequest Начало нуля не допускается Access-Control-Allow-Origin для файла: /// к файлу: /// (без сервера)
Cross-site XMLHttpRequest

Опять же, в крайнем случае я загружаю все данные при загрузке веб-страницы. Это может привести к задержке загрузки веб-страницы до 10 секунд, которая не нужна для 90% пользователей приложения..

Спасибо за любые предложения / альтернативы !!!

Ответы [ 3 ]

4 голосов
/ 20 января 2011

Я думаю Я понял это.

Все, что мне действительно нужно было сделать, это добавить обратный вызов в мой тег <script>. Конечный код:

У меня есть элемент с именем next ... Итак, в функции $("#next").click() у меня есть следующий код. Это выполняется, только если они нажимают «далее».

//remove old dynamically written script tag-    
       var old = document.getElementById('uploadScript');  
   if (old != null) {  
     old.parentNode.removeChild(old);  
     delete old;  
   } 

   var head = document.getElementsByTagName("head")[0];  
   script = document.createElement('script');  
   script.id = 'uploadScript';  
   script.type = 'text/javascript';  
   script.src = 'test/' + scope_dir + '/js/list.js';  
   script.onload = refresh_page;    
   head.appendChild(script);  


function refresh_page(){  
   //perform action with data loaded from the .js file.  
}  

Это похоже на работу и позволяет Chrome динамически загружать файлы .js в локальную файловую систему, обходя политику контроля доступа и разрешения, с которой я столкнулся при попытке использовать функции jQuery.

2 голосов
/ 25 января 2011

Ладно, много потрудился и потратил много времени. Но я понял это. Решение в моем последнем ответе прекрасно работает как для Chrome, так и для Mozilla. Но это не работает для благословенного IE, потому что IE не будет запускать событие onload: он думает, что он обработал все загрузки в этом файле, и вы не можете заставить его сделать еще одну. Тем не менее, IE очень рад загрузить файл с помощью функции getScript JQuery (которую Chrome не разрешит из-за политики ccess-control-allow-origin) - для этого вам понадобятся библиотеки JQuery. Итак, вот что я закончил:

function getMyText(){
    var url='mylocalfile.js';
    if (jQuery.support.scriptEval) { 
        var old = document.getElementById('uploadScript');  
        if (old != null) {  
             old.parentNode.removeChild(old);  
             delete old;  
            } 
        var head = document.getElementsByTagName("head")[0]; 
        var script = document.createElement('script');
        script.id = 'uploadScript';
        script.type = 'text/javascript';
        script.onload = refresh_page; 
        script.src = url; 
        head.appendChild(script);  
    } else {
       $.getScript(url,function(){
            refresh_page();
      });
     }
}

function refresh_page() {
    alert(mytext);
}

Во всем этом mylocaltext.js определяет весь мой html как содержимое переменной mytext. Уродливо, но это работает. jQuery.support.scriptEval имеет значение true для интеллектуальных браузеров, которые запускают события загрузки при изменении DOM. IE нет, поэтому отправляет его в .getScript; Chrome и другие делают, так что отправляет их в другую сторону. В любом случае это работает с локальными файлами.

1 голос
/ 25 января 2011

Интересно, но как я могу использовать одну и ту же технику для загрузки всего файла HTML? Проблема, аналогичная вашей, - у меня есть сотни HTML-файлов, которые я хочу включить в веб-страницу, в зависимости от того, что хочет видеть пользователь. Кажется, я могу использовать эту технику для загрузки всей HTML-страницы, что-то вроде:

script.id = 'uploadScript';
script.type = 'text/html';
script.src = url; 
script.onload = refresh_page; 
head.appendChild(script);  

т. Е. Скажите загрузку в HTML. Я вижу из консоли, что он загружает его на страницу, и получаю сообщение «Ресурс интерпретирован как скрипт, но передан с типом MIME text / html». Но я не могу придумать, как найти HTML-код, загруженный и содержащийся в скрипте

...