Ошибка XmlHttpRequest: исходный null не разрешен Access-Control-Allow-Origin

Я разрабатываю страницу, которая извлекает изображения из Flickr и Panoramio через поддержку AJAX jQuery.

сторона Flickr работает нормально, но когда я пытаюсь $.get(url, callback) из Panoramio я вижу ошибку в консоли Chrome:

XMLHttpRequest не удается загрузить http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150 - ... Origin null не допускается Access-Control-Allow-Origin.

Если я запрашиваю этот URL из браузера напрямую, он работает нормально. Что происходит, и могу ли я обойти это? Я составляю свой запрос неправильно, или это то, что Panoramio делает, чтобы помешать тому, что я пытаюсь сделать?

Google не обнаружил никаких полезных матчей на сообщение об ошибке.

редактировать

вот пример кода, который показывает проблема:

$().ready(function () {
  var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150';

  $.get(url, function (jsonp) {
    var processImages = function (data) {
      alert('ok');
    };

    eval(jsonp);
  });
});

вы можете запустите пример в интернете.

Изменить 2

спасибо Дарину за его помощь в этом. ПРИВЕДЕННЫЙ ВЫШЕ КОД НЕВЕРЕН. используйте этот код:

$().ready(function () {
  var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&minx=-30&miny=0&maxx=0&maxy=150&callback=?';

  $.get(url, function (data) {
    // can use 'data' in here...
  });
});

16 ответов


для протокола, насколько я могу судить, у вас было две проблемы:--18-->

  1. вы не передавали спецификатор типа "jsonp" вашему $.get, поэтому он использовал обычный XMLHttpRequest. Однако ваш браузер поддерживал CORS (общий доступ к ресурсам Cross-Origin), чтобы разрешить междоменный XMLHttpRequest, если сервер его использовал. Вот где пришла.

  2. я думаю, вы упомянули, что вы запускали его из файла: / / URL. Есть два способа для заголовков CORS сигнализировать, что междоменный XHR в порядке. Один-послать Access-Control-Allow-Origin: * (который, если вы достигли Flickr через $.get, Они, должно быть, делали), в то время как другой должен был Эхо назад содержимое Origin заголовок. Однако,file:// URLs производят null Origin который не может быть авторизован через echo-back.

первый был решен окольным путем предложением Дарина использовать $.getJSON. Это немного волшебство, чтобы изменить тип запроса от его значение по умолчанию "json "для" jsonp", если он видит подстроку callback=? в URL.

это решило второе, больше не пытаясь выполнить запрос CORS от file:// URL-адрес.

чтобы уточнить для других людей, вот простые инструкции по устранению неполадок:

  1. если вы пытаетесь использовать JSONP, убедитесь, что один из следующих случаев:
    • вы используете $.get и set dataType в jsonp.
    • вы используете $.getJSON и включен callback=? в URL.
  2. если вы пытаетесь выполнить междоменный XMLHttpRequest через CORS...
    1. убедитесь, что вы тестируете через http://. Скрипты, запущенные через file:// имеют ограниченную поддержку CORS.
    2. убедитесь, что браузер фактически поддерживает CORS. (Opera и Internet Explorer опаздывают на вечеринку)

возможно, вам нужно добавить заголовок в вызываемый скрипт, вот что я должен был сделать в PHP:

header('Access-Control-Allow-Origin: *');

Подробнее кросс-доменный AJAX-ОУ, веб-служб (по-французски).


для простого HTML-проекта:

cd project
python -m SimpleHTTPServer 8000

выберите файл.


работает для меня на Google Chrome v5.0.375.127 (я получаю предупреждение):

$.get('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150',
function(json) {
    alert(json.photos[1].photoUrl);
});

также я бы рекомендовал вам использовать $.getJSON() метод вместо этого, как и предыдущий не работает на IE8 (по крайней мере на моей машине):

$.getJSON('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150', 
function(json) {
    alert(json.photos[1].photoUrl);
});

вы можете онлайн отсюда.


обновление:

теперь, когда вы показали свой код, я вижу с этим проблем. У вас есть как анонимная функция, так и встроенная функция, но оба будут называться processImages. Вот как работает поддержка JSONP jQuery. Обратите внимание, как я определяю callback=? чтобы вы могли использовать анонимную функцию. Вы можете прочитать больше об этом в документации.

еще одно замечание: вы не должны звонить эвалу. Параметр, переданный вашей анонимной функции, уже будет проанализирован в JSON с помощью jQuery.


пока запрашиваемый сервер поддерживает формат данных JSON, используйте интерфейс JSONP (JSON Padding). Это позволяет вам делать внешние доменные запросы без прокси-серверов или причудливых заголовков.


Это та же политика происхождения, вы должны использовать интерфейс JSON-P или прокси, работающий на том же хосте.


нам удалось это через http.conf файл (отредактирован и перезапущен службой HTTP):

<Directory "/home/the directory_where_your_serverside_pages_is">
    Header set Access-Control-Allow-Origin "*"
    AllowOverride all
    Order allow,deny
    Allow from all
</Directory>

на Header set Access-Control-Allow-Origin "*", вы можете поставить точный URL.


Если вы выполняете локальное тестирование или вызываете файл из чего-то вроде file:// тогда вам нужно отключить безопасность браузера.

на MAC: open -a Google\ Chrome --args --disable-web-security


в моем случае тот же код отлично работал в Firefox, но не в Google Chrome. Консоль JavaScript Google Chrome сказала:

XMLHttpRequest cannot load http://www.xyz.com/getZipInfo.php?zip=11234. 
Origin http://xyz.com is not allowed by Access-Control-Allow-Origin.
Refused to get unsafe header "X-JSON"

мне пришлось удалить часть www URL Ajax, чтобы она правильно соответствовала исходному URL-адресу, и тогда она работала нормально.


Не все серверы поддерживают jsonp. Это требует, чтобы сервер установил функцию обратного вызова в его результатах. Я использую это, чтобы получить ответы json с сайтов, которые возвращают чистый json, но не поддерживают jsonp:

function AjaxFeed(){

    return $.ajax({
        url:            'http://somesite.com/somejsonfile.php',
        data:           {something: true},
        dataType:       'jsonp',

        /* Very important */
        contentType:    'application/json',
    });
}

function GetData() {
    AjaxFeed()

    /* Everything worked okay. Hooray */
    .done(function(data){
        return data;
    })

    /* Okay jQuery is stupid manually fix things */
    .fail(function(jqXHR) {

        /* Build HTML and update */
        var data = jQuery.parseJSON(jqXHR.responseText);

        return data;
    });
}

Я использую сервер Apache, поэтому я использовал модуль mod_proxy. Включить модули:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

потом добавил:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

наконец, передайте прокси-url вашему скрипту.


в качестве заключительной ноты документация Mozilla явно говорит это

приведенный выше пример завершится ошибкой, если заголовок будет помечен как: Access-Control-Allow-Origin: *. поскольку Access-Control-Allow-Origin явно упоминает http://foo.пример, содержимое credential-cognizant возвращается в вызывающий веб содержание.

Как следствие-это не просто плохая практика, чтобы использовать '*'. Просто делать не работать:)


Я также получил ту же ошибку в Chrome (я не проверяла другие браузеры). Это было из-за того, что я двигался дальше. domain.com вместо www.domain.com - ... Немного странно ,но я мог бы решить проблему, добавив следующие строки.реврайт. Он перенаправляет domain.com к www.domain.com и проблема была решена. Я ленивый веб-посетитель, поэтому я почти никогда не печатаю www, но, по-видимому, в некоторых случаях это требуется.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/ [R=301,L]

убедитесь, что вы используете последнюю версию jQuery. Мы столкнулись с этой ошибкой для JQuery 1.10.2, и ошибка была решена после использования JQuery 1.11.1


люди,

Я столкнулся с аналогичной проблемой. Но, используя Fiddler, я смог добраться до проблемы. Проблема в том, что URL-адрес клиента, настроенный в реализации CORS на стороне веб-API,не должен иметь косой черты. После отправки запроса через Google Chrome и проверьте TextView на заголовки раздел скрипача, сообщение об ошибке гласит что-то вроде этого:

*"указанное происхождение политики your_client_url:/' является недопустимым. Он не может заканчиваться косой чертой."

Это очень странно, потому что он работал без каких-либо проблем в Internet Explorer, но дал мне головную боль при тестировании с помощью Google Chrome.

Я удалил косую черту в коде CORS и перекомпилировал веб-API, и теперь API доступен через Chrome и Internet Explorer без каких-либо проблем. Пожалуйста, попробуй.

спасибо, Энди!--1-->


в опубликованном решении есть небольшая проблема по CodeGroover выше, где, если вы измените файл, вам придется перезапустить сервер, чтобы фактически использовать обновленный файл (по крайней мере, в моем случае).

Так что поиск немного, я нашел этот использование:

sudo npm -g install simple-http-server # to install
nserver # to use

и тогда он будет служить в http://localhost:8000.