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

Я сделал небольшой 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 не может быть выполнена таким образом, то совет как еще сделать это было бы здорово.

8 ответов

Решение

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

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

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

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

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

Решение: используйте Fire fox или загрузите свои данные на временный сервер. Если вы все еще хотите использовать 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

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

Просто хотел добавить, что ответ "запустить веб-сервер" кажется довольно устрашающим, но если у вас есть 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

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

Я хотел бы смиренно добавить, что согласно этому источнику SO: /questions/8202970/jquery-ajax-zapuskaetsya-kak-lokalnyij-fajl-html-izbegaya-sop-ta-zhe-politika-proishozhdeniya/8202976#8202976, этот тип проблем теперь частично решается просто с помощью следующей инструкции jQuery:

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

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

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

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

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

--allow-file-access-from-files

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

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

Яваскрипты:

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);

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

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

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

Используя Java Spring для запуска веб-службы, вам необходимо добавить:@ServletComponentScanпрямо над@SpringBootApplicationв вашем автоматически сгенерированном файле YouAppApplication.java (тот, который имеет функцию main()) и создайте класс со следующей реализацией:

      @WebFilter("/*")
public class AddResponseHeaderFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // ...
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        httpServletResponse.addHeader("Access-Control-Allow-Origin", "null");

        httpServletResponse.addHeader("Access-Control-Allow-Credentials", "true");
         filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        // ...
    }
}

обратите внимание, что вы можете выбрать другое имя для этого класса, как только он реализует фильтр и имеет@WebFilterаннотацию, вы также можете указать подстановочный знак, отличный от/*поэтому этот фильтр не применяется к каждой конечной точке.
Как указано @Louis Loudog Trottier, вам нужно добавить...withCredentials = true;при создании запроса Ajax, чтобы это работало.

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

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

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

mydata.js:

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

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

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