Нулевой источник не разрешен Access-Control-Allow-Origin

184

Я сделал небольшой xslt-файл для создания вывода html с именем weather.xsl с кодом следующим образом:

<!-- DWXMLSource="http://weather.yahooapis.com/forecastrss?w=38325&u=c" -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="yweather"
xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <img src="{/*/*/item/yweather:condition/@text}.jpg"/>
</xsl:template>
</xsl:stylesheet>

Я хочу загрузить в вывод html в div в html-файле, что я пытаюсь сделать с помощью jQuery следующим образом:

<div id="result">
<script type="text/javascript">
$('#result').load('weather.xsl');
</script>
</div>

Но я получаю следующую ошибку: Нулевой источник не разрешен Access-Control-Allow-Origin.

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

dudledok
источник
Это ваш настоящий load звонок? Там вообще нет пути?
TJ Crowder

Ответы:

227

Origin null- это локальная файловая система, поэтому она предполагает, что вы загружаете HTML-страницу, которая выполняет loadвызов, через file:///URL-адрес (например, просто дважды щелкаете по ней в локальном файловом браузере или аналогичном). Различные браузеры используют разные подходы к применению одной и той же политики происхождения к локальным файлам.

Я предполагаю, что вы видите это с помощью Chrome. Правила Chrome для применения SOP к локальным файлам очень жесткие, он запрещает даже загрузку файлов из того же каталога, что и документ. Так же как и Опера. Некоторые другие браузеры, такие как Firefox, разрешают ограниченный доступ к локальным файлам. Но в основном использование ajax с локальными ресурсами не будет работать кросс-браузерно.

Если вы просто тестируете что-то локальное, что вы действительно будете развертывать в Интернете, а не используете локальные файлы, установите простой веб-сервер и http://вместо этого тестируйте по URL-адресам. Это дает вам гораздо более точную картину безопасности.

TJ Crowder
источник
1
После того, как я загрузил его, я больше не получаю нулевое значение Origin, но я все еще получаю «не разрешено Access-Control-Allow-Origin».
Дудледок
3
Если загружаемый вами ресурс соответствует указанному вами ( $('#result').load('weather.xsl');), этого не должно произойти, поскольку запрос явно имеет тот же источник. Если вы пытаетесь загрузить откуда-то еще (например, $('#result').load('http://somewhere.else/weather.xsl');), то вы снова запускаете SOP, но другим способом. Запросы Ajax ограничены одним и тем же источником (см. Ссылку в ответе), или если вы используете браузер с поддержкой CORS, а сервер поддерживает COR, сервер может выбрать, разрешить ли запрос перекрестного источника.
TJ Crowder
Я изменил URL загрузки. Изменение его обратно на тот, что в вопросе делает загрузку нормально. Спасибо за помощь
дудледок
2
Какой самый простой и быстрый способ настроить простой веб-сервер? IIS был бы самым простым способом здесь?
Кьяран Галлахер
13
@ CiaranG Я бежал python -m SimpleHTTPServerиз командной строки, а затем пошел к localhost: 8000, работал для меня. Python поставляется с предустановленной Mac OS X; вам может потребоваться установить, если вы используете другую ОС.
Дейв Лиепманн
216

В Chrome и Safari есть ограничение на использование ajax с локальными ресурсами. Вот почему выдает ошибку вроде

Нулевой источник не разрешен Access-Control-Allow-Origin.

Решение: используйте Firefox или загрузите свои данные на временный сервер. Если вы все еще хотите использовать Chrome, запустите его с опцией ниже;

--allow-file-access-from-files

Подробнее о том, как добавить вышеуказанный параметр в Chrome: щелкните правой кнопкой мыши значок Chrome на панели задач, щелкните правой кнопкой мыши Google Chrome во всплывающем окне, выберите «Свойства» и добавьте вышеуказанный параметр в текстовое поле «Цель» на вкладке «Ярлык». Это понравится как ниже;

C:\Users\XXX_USER\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files

Надеюсь, это поможет!

Гоханский танк
источник
19
В Mac OS X вы можете запустить Chrome с этой опцией, открыв терминал и введя: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files & Обратите внимание, что окончательный вариант - это просто, так что вы можете продолжать использовать терминал и не требуется. ПРИМЕЧАНИЕ. Если вы закроете терминал, он закроет окно Chrome.
Бруно Бернардино
3
Сделал все это и закрыл и открыл. до сих пор не ходят (Chrome 27.0.1453.116 м на XP)
mplungjan
Я не могу добавить этот параметр в Windows 8 ..., кто-нибудь, кто знает, как это сделать? ...
Морти
Я буду работает с веб - сервера. Какого черта? Как я могу выяснить, куда он загружает локальные файлы?
Энди
Когда я пытаюсь добавить --allow-file-access-from-files к целевому пути, я получаю сообщение «.... неверный», все еще ли его решение действительно?
Алекс
48

Просто хотел добавить, что ответ «запустить веб-сервер» кажется довольно пугающим, но если у вас есть python в вашей системе (установлен по умолчанию, по крайней мере, на MacOS и любом дистрибутиве Linux), это так просто, как:

python -m http.server  # with python3

или

python -m SimpleHTTPServer  # with python2

Итак, если у вас есть html-файл myfile.htmlв папке, скажем mydir, все, что вам нужно сделать, это:

cd /path/to/mydir
python -m http.server  # or the python2 alternative above

Затем укажите ваш браузер на:

http://localhost:8000/myfile.html

И вы сделали! Работает во всех браузерах , без отключения веб-безопасности, разрешения локальных файлов или даже перезапуска браузера с параметрами командной строки.

gozzilli
источник
2
Эквивалент python 3 для Windows: python -m http.server [<portNo>]
Арагорн
Python 3: python3 -m http.server
Жуан Нуньес
Python 2 в Linux, выбирая порт 8080 (или любой другой, который вы хотите):python -m SimpleHTTPServer 8080
Rodrigo
2

Я хотел бы смиренно добавить, что согласно этому источнику SO: https://stackoverflow.com/a/14671362/1743693 , этот тип проблем теперь частично решается просто с помощью следующей инструкции jQuery:

<script> 
    $.support.cors = true;
</script>

Я попробовал это на IE10.0.9200, и он сразу же заработал (используя jquery-1.9.0.js).

На chrome 28.0.1500.95 - эта инструкция не работает (это происходит повсеместно, поскольку Дэвид жалуется в комментариях по ссылке выше)

Запуск chrome с --allow-file-access-from-files у меня не сработал (как утверждают Maistora выше)

orberkov
источник
2

Добавим немного, чтобы использовать решение Гохана для использования:

--allow-file-access-from-files

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

Саурабх
источник
Параметр уже был представлен Ghokan Tank, и выяснение того, как всегда запускать браузер с этим параметром, не является частью вопроса. Кроме того, вы не можете предполагать, что все используют Microsoft Windows.
13
0

Я искал решение сделать XHR-запрос к серверу из локального файла HTML и нашел решение с использованием Chrome и PHP. (без Jquery)

Javascripts:

var x = new XMLHttpRequest(); 
if(x) x.onreadystatechange=function(){ 
    if (x.readyState === 4 && x.status===200){
        console.log(x.responseText); //Success
    }else{ 
        console.log(x); //Failed
    }
};
x.open(GET, 'http://example.com/', true);
x.withCredentials = true;
x.send();

Заголовок запроса моего Chrome Origin: null

Мой ответный заголовок PHP (обратите внимание, что 'null' является строкой ). HTTP_REFERER разрешает перекрестный источник с удаленного сервера на другой.

header('Access-Control-Allow-Origin: '.(trim($_SERVER['HTTP_REFERER'],'/')?:'null'),true);
header('Access-Control-Allow-Credentials:true',true);

Мне удалось успешно подключиться к моему серверу. Вы можете игнорировать заголовки учетных данных, но это работает для меня с AuthType Basicвключенным Apache

Я проверил совместимость с FF и Opera, он работает во многих случаях, таких как:

С IP-адреса виртуальной локальной сети (192.168.0.x) обратно на WAN (общедоступный) IP-адрес
виртуальной машины: с IP-адреса виртуальной локальной сети обратно на имя домена удаленного сервера.
Из локального файла .HTML в IP-адрес виртуальной локальной сети и / или IP-адрес виртуальной локальной сети:
из локального файла .HTML в доменное имя удаленного сервера.
И так далее.

Луи Лоудог Троттье
источник
0

Вы можете загрузить локальный файл Javascript (в дереве под file:/исходной страницей), используя тег источника:

<script src="my_data.js"></script>

Если вы кодируете свой ввод в Javascript, как в этом случае:

mydata.js :

$xsl_text = "<xsl:stylesheet version="1.0" + ....

(это проще для json), тогда у вас есть «данные» в глобальной переменной Javascript для использования по вашему желанию.

Богатый
источник