Ошибка XmlHttpRequest: нулевой источник не разрешен Access-Control-Allow-Origin - PullRequest
528 голосов
/ 29 августа 2010

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

Сторона 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. Нулевой источник не разрешен Access-Control-Allow-Origin.

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

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

EDIT

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

$().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 ]

416 голосов
/ 19 сентября 2010

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

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

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

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

Это решило вторую, больше не пытаясь выполнитьЗапрос CORS с file:// URL.

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

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

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

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

Подробнее в Кросс-домен AJAX ou services WEB (по-французски).

68 голосов
/ 07 марта 2012

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

cd project
python -m SimpleHTTPServer 8000

Затем просмотрите файл.

20 голосов
/ 29 августа 2010

У меня работает в 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);
});

Вы можете попробовать онлайн здесь .


UPDATE:

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

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

8 голосов
/ 06 мая 2011

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

5 голосов
/ 29 августа 2010

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

4 голосов
/ 20 августа 2013

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

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

4 голосов
/ 29 июля 2011

Нам удалось это сделать с помощью файла 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-адрес.

3 голосов
/ 03 января 2012

В моем случае, тот же код отлично работал в 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-адресом, и тогда он работал нормально.

2 голосов
/ 19 октября 2013

Не все серверы поддерживают 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;
    });
}
...