Ошибка 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-->
вы не передавали спецификатор типа "jsonp" вашему
$.get
, поэтому он использовал обычный XMLHttpRequest. Однако ваш браузер поддерживал CORS (общий доступ к ресурсам Cross-Origin), чтобы разрешить междоменный XMLHttpRequest, если сервер его использовал. Вот где пришла.я думаю, вы упомянули, что вы запускали его из файла: / / URL. Есть два способа для заголовков CORS сигнализировать, что междоменный XHR в порядке. Один-послать
Access-Control-Allow-Origin: *
(который, если вы достигли Flickr через$.get
, Они, должно быть, делали), в то время как другой должен был Эхо назад содержимоеOrigin
заголовок. Однако,file://
URLs производят nullOrigin
который не может быть авторизован через echo-back.
первый был решен окольным путем предложением Дарина использовать $.getJSON
. Это немного волшебство, чтобы изменить тип запроса от его значение по умолчанию "json "для" jsonp", если он видит подстроку callback=?
в URL.
это решило второе, больше не пытаясь выполнить запрос CORS от file://
URL-адрес.
чтобы уточнить для других людей, вот простые инструкции по устранению неполадок:
- если вы пытаетесь использовать JSONP, убедитесь, что один из следующих случаев:
- вы используете
$.get
и setdataType
вjsonp
. - вы используете
$.getJSON
и включенcallback=?
в URL.
- вы используете
- если вы пытаетесь выполнить междоменный XMLHttpRequest через CORS...
- убедитесь, что вы тестируете через
http://
. Скрипты, запущенные черезfile://
имеют ограниченную поддержку CORS. - убедитесь, что браузер фактически поддерживает CORS. (Opera и Internet Explorer опаздывают на вечеринку)
- убедитесь, что вы тестируете через
возможно, вам нужно добавить заголовок в вызываемый скрипт, вот что я должен был сделать в PHP:
header('Access-Control-Allow-Origin: *');
Подробнее кросс-доменный AJAX-ОУ, веб-служб (по-французски).
работает для меня на 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
.