Ошибка XmlHttpRequest: Происхождение null не разрешено Access-Control-Allow-Origin
Я разрабатываю страницу, которая извлекает изображения из Flickr и Panoramio через поддержку jQuery 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. Происхождение 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...
});
});
Ответы
Ответ 1
Для записи, насколько я могу судить, у вас было две проблемы:
-
Вы не передавали спецификатор типа "jsonp" на ваш $.get
, поэтому он использовал обычный XMLHttpRequest. Тем не менее, ваш браузер поддерживает CORS (совместное использование ресурсов Cross-Origin), чтобы разрешить междоменный XMLHttpRequest, если сервер одобрил его. Это где заголовок Access-Control-Allow-Origin
.
-
Я полагаю, вы упомянули, что используете его из файла://URL. Для заголовков CORS есть два способа указать, что междоменный XHR в порядке. Один из них - отправить Access-Control-Allow-Origin: *
(который, если вы дошли до Flickr через $.get
, они, должно быть, делали), в то время как другой должен был отследить содержимое заголовка Origin
. Однако file://
URL-адреса создают нуль Origin
, который не может быть разрешен посредством эхо-возврата.
Первая была решена окольным путем Даринским предложением использовать $.getJSON
. Для изменения типа запроса с его по умолчанию "json" на "jsonp" возникает небольшая магия, если он видит подстроку callback=?
в URL-адресе.
Это решило второе, больше не пытаясь выполнить запрос CORS с URL file://
.
Чтобы уточнить для других людей, выполните следующие простые инструкции по устранению неполадок:
- Если вы пытаетесь использовать JSONP, убедитесь, что одно из следующего:
- Вы используете
$.get
и установите dataType
на jsonp
.
- Вы используете
$.getJSON
и включаете callback=?
в URL.
- Если вы пытаетесь выполнить междоменный XMLHttpRequest через CORS...
- Убедитесь, что вы тестируете через
http://
. Скрипты, запущенные через file://
, имеют ограниченную поддержку CORS.
- Убедитесь, что браузер фактически поддерживает CORS. (Opera и Internet Explorer опаздывают на вечеринку)
Ответ 2
Вам нужно добавить HEADER в ваш вызываемый script, вот что мне нужно было сделать в PHP:
header('Access-Control-Allow-Origin: *');
Подробнее в Перекрестный домен AJAX ou services WEB (на французском языке).
Ответ 3
Для простого проекта HTML:
cd project
python -m SimpleHTTPServer 8000
Затем просмотрите файл.
Ответ 4
Работает для меня в 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
. Это работает поддержка JQuery JSONP. Обратите внимание, как я определяю callback=?
, чтобы вы могли использовать анонимную функцию. Вы можете прочитать об этом в документации.
Еще одно замечание: вы не должны называть eval. Параметр, переданный вашей анонимной функции, уже будет разбираться в JSON с помощью jQuery.
Ответ 5
Пока запрашиваемый сервер поддерживает формат данных JSON, используйте интерфейс JSONP (JSON Padding). Это позволяет вам делать запросы внешнего домена без прокси-серверов или причудливых заголовков.
Ответ 6
В той же политике происхождения вы должны использовать интерфейс JSON-P или прокси-сервер, работающий на том же хосте.
Ответ 7
Мы справились с ней через файл 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.
Ответ 8
Если вы выполняете локальное тестирование или вызываете файл с чего-то вроде file://
, вам необходимо отключить защиту браузера.
В MAC:
open -a Google\ Chrome --args --disable-web-security
Ответ 9
В моем случае тот же код отлично работал на Firefox, но не в Google Chrome. Google Chrome консоль Google сказал:
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-адресу, и тогда он работал нормально.
Ответ 10
Не все серверы поддерживают 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;
});
}
Ответ 11
Я использую сервер 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 на ваш script.
Ответ 12
Как окончательная заметка документация Mozilla явно говорит, что
Приведенный выше пример завершился неудачей, если заголовок был подстановочным знаком: Access-Control-Allow-Origin: *. Так как Access-Control-Allow-Origin явно упоминает http://foo.example, содержимое учетно-зависимой информации возвращается в вызывающий веб-сайт содержание.
Как следствие, это не просто плохая практика использования "*". Просто не работает:)
Ответ 13
Существует небольшая проблема в решении, опубликованном CodeGroover выше, где, если вы меняете файл, вам придется перезапустить сервер, чтобы фактически использовать обновленный файл (по крайней мере, в моем случае).
Поэтому, немного поискав, я нашел это:
sudo npm -g install simple-http-server # to install
nserver # to use
И тогда он будет работать на http://localhost:8000
.
Ответ 14
Я также получил ту же ошибку в Chrome (я не тестировал других броузеров). Это было связано с тем, что я перешел на domain.com вместо www.domain.com. Немного странно, но я мог бы решить проблему, добавив следующие строки в .htaccess. Он перенаправляет domain.com на www.domain.com, и проблема решена. Я ленивый веб-посетитель, поэтому я почти никогда не набираю www, но, по-видимому, в некоторых случаях это требуется.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
Ответ 15
Убедитесь, что вы используете последнюю версию JQuery. Мы столкнулись с этой ошибкой для JQuery 1.10.2, и ошибка была решена после использования JQuery 1.11.1
Ответ 16
Люди,
У меня возникла аналогичная проблема. Но, используя Fiddler, я смог понять эту проблему. Проблема заключается в том, что URL-адрес клиента, который настроен в реализации CORS на стороне веб-API, не должен иметь завершающего косая черта. После отправки запроса через Google Chrome и ознакомьтесь с вкладкой TextView раздела Заголовки Fiddler, в сообщении об ошибке будет указано примерно следующее:
* "Указанное политическое происхождение your_client_url:/'недействительно. Он не может закончиться косой чертой."
Это настоящая причуда, потому что она работала без каких-либо проблем в Internet Explorer, но при тестировании с использованием Google Chrome у меня была головная боль.
Я удалил косую черту в коде CORS и перекомпилировал веб-API, и теперь API доступен через Chrome и Internet Explorer без каких-либо проблем. Пожалуйста, сделайте это.
Спасибо,
Andy
Ответ 17
Я не знаю, почему @echox похоронил свой ответ в комментариях, но
Его ответ - именно то, что мне нужно!
Мне надоело отлаживать наш сайт с помощью Chrome: мне нужно загрузить файлы или взломать локальный сервер для себя.
Некоторые браузеры, такие как chrome, разрешают CORS, если они запускаются с параметром --allow-file-access-from-files - echox 12 июня 12 в 16:20
Никогда бы не увидел это, если бы мне не было скучно пролистывать.
Поскольку задание похожих вопросов просто помечается как дубликат, даже если я хочу получить ответ с программным отключением/обход кода.