IE9 jQuery AJAX с CORS возвращает "Доступ запрещен"
Во всех браузерах работает кроме IE (я тестирую в IE 9).
jQuery.support.cors = true;
...
$.ajax(
url + "messages/postMessageReadByPersonEmail",
{
crossDomain: true,
data: {
messageId : messageId,
personEmail : personEmail
},
success: function() {
alert('marked as read');
},
error: function(a,b,c) {
alert('failed');
},
type: 'post'
}
);
У меня есть другая функция, которая использует dataType: 'jsonp'
, но мне не нужны никакие данные, возвращаемые этим вызовом AJAX. Моим последним прибегнуть к возврату какого-то смеха, завернутого в JSONP, чтобы заставить его работать.
Любые идеи, почему IE завораживает запрос CORS, который не возвращает данные?
Ответы
Ответ 1
Это известный bug с jQuery. Команда jQuery "не планирует поддерживать это в ядре и лучше подходит как плагин". (См. этот комментарий).
IE не использует XMLHttpRequest, а альтернативный объект с именем XDomainRequest.
Существует плагин для поддержки этого в jQuery, который можно найти здесь:
https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js
ИЗМЕНИТЬ
Функция $.ajaxTransport
регистрирует транспортер factory. Транспортер используется внутри $.ajax
для выполнения запросов. Поэтому я предполагаю, что вы должны называть $.ajax
, как обычно. Информацию о перевозчиках и расширении $.ajax
можно найти здесь здесь.
Кроме того, возможно более совершенную версию этого плагина можно найти здесь.
Две другие заметки:
Изменить 2: проблема с http на https
Запросы должны быть нацелены на ту же схему, что и страница хостинга
Это ограничение означает, что если ваша страница AJAX находится на http://example.com, тогда ваш целевой URL должен также начинаться с HTTP. Аналогично, если ваша страница AJAX находится в https://example.com, целевой URL должен также начинаться с HTTPS.
Источник: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
Ответ 2
Создав принятый ответ @dennisg, я успешно выполнил это с помощью jQuery.XDomainRequest.js от MoonScript.
Следующий код работал правильно в Chrome, Firefox и IE10, но не прошел в IE9. Я просто включил script, и теперь он автоматически работает в IE9. (И, вероятно, 8, но я его не тестировал.)
var displayTweets = function () {
$.ajax({
cache: false,
type: 'GET',
crossDomain: true,
url: Site.config().apiRoot + '/Api/GetTwitterFeed',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
for (var tweet in data) {
displayTweet(data[tweet]);
}
}
});
};
Ответ 3
Полные инструкции о том, как это сделать, используя плагин jQuery-ajaxTransport-XDomainRequest, можно найти здесь:
https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest#instructions
Этот плагин активно поддерживается и обрабатывает HTML, JSON и XML. Файл также размещен на CDNJS, поэтому вы можете напрямую удалить script на свою страницу без дополнительной настройки:
http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1/jquery.xdomainrequest.min.js
Ответ 4
Проблема в том, что IE9 и ниже не поддерживают CORS. XDomainRequest поддерживает только GET/POST и text/plain
conten-type, как описано здесь: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
Итак, если вы хотите использовать все HTTP-глаголы и/или json и т.д., вам нужно использовать другое решение. Я написал прокси-сервер, который будет изящно понижать до проксирования, если используется IE9 или меньше. Вам не нужно менять свой код вообще, если вы используете ASP.NET.
Решение состоит из двух частей. Первый - это jquery script, который перехватывает обработку jQuery ajax. Он будет автоматически вызывать веб-сервер, если будет выполнен запрос crossDomain, а браузер - IE:
$.ajaxPrefilter(function (options, originalOptions, jqXhr) {
if (!window.CorsProxyUrl) {
window.CorsProxyUrl = '/corsproxy/';
}
// only proxy those requests
// that are marked as crossDomain requests.
if (!options.crossDomain) {
return;
}
if (getIeVersion() && getIeVersion() < 10) {
var url = options.url;
options.beforeSend = function (request) {
request.setRequestHeader("X-CorsProxy-Url", url);
};
options.url = window.CorsProxyUrl;
options.crossDomain = false;
}
});
На вашем веб-сервере вы должны получить запрос, получить значение из HTTP-заголовка X-CorsProxy-Url и выполнить HTTP-запрос и, наконец, вернуть результат.
Мое сообщение в блоге: http://blog.gauffin.org/2014/04/how-to-use-cors-requests-in-internet-explorer-9-and-below/
Ответ 5
Я просто сделал все запросы JSONP, потому что это единственное решение для всех наших поддерживаемых браузеров (IE7 + и постоянных пользователей). Имейте в виду, ваш ответ технически работает для IE9, поэтому у вас есть правильный ответ.
Ответ 6
Получение междоменного JSON с jQuery в Internet Explorer 8 и более поздних версиях
Очень полезная ссылка:
http://graphicmaniacs.com/note/getting-a-cross-domain-json-with-jquery-in-internet-explorer-8-and-later/
Может помочь с проблемой возврата json из запроса домена X.
Надеюсь, это поможет кому-то.
Ответ 7
Основываясь на решении MoonScript, вы можете попробовать это:
https://github.com/intuit/xhr-xdr-adapter/blob/master/src/xhr-xdr-adapter.js
Преимущество состоит в том, что, поскольку это решение более низкого уровня, оно позволит CORS (насколько это возможно) IE 8/9 с другими фреймворками, а не только с jQuery. Я успешно использовал его с помощью AngularJS, а также jQuery 1.x и 2.x.
Ответ 8
Чтобы решить эту проблему, проверьте также, есть ли в вашем файле ajax некоторые .js:
Я получил ошибку Access denied, включая shadowbox.js в моем ajax.php
Ответ 9
Я тестировал веб-сервис CORS на своей машине dev и получал сообщение об ошибке "Отказано в доступе" только в IE. Firefox и Chrome отлично работали. Оказывается, это было вызвано моим использованием localhost в вызове ajax! Поэтому мой URL-адрес браузера был примерно таким:
http://my_computer.my_domain.localhttps://stackoverflow.com/CORS_Service/test.html
и мой вызов ajax внутри test.html был примерно таким:
//fails in IE
$.ajax({
url: "http://localhost/CORS_Service/api/Controller",
...
});
Все работало, как только я изменил вызов ajax, чтобы использовать свой IP-адрес компьютера вместо localhost.
//Works in IE
$.ajax({
url: "http://192.168.0.1/CORS_Service/api/Controller",
...
});
В окне инструментов разработчика IE на вкладке "Сеть" также отображается запрос CORS Preflight OPTIONS, за которым следует XMLHttpRequest GET, что я и ожидал увидеть.
Ответ 10
Обновление с начала 2015 года. xDomain - широко используемая библиотека для поддержки CORS на IE9 с ограниченным дополнительным кодированием.
https://github.com/jpillora/xdomain
Ответ 11
Попробуйте использовать jquery-transport-xdr плагин jQuery для запросов CORS в IE8/9.
Ответ 12
Примечание - Примечание
не использовать " http://www.domain.xxx" или " http://localhost/" или "IP → 127.0.0.1" для URL-адреса в ajax.
используйте только путь (каталог) и имя страницы без адреса.
ложное состояние:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir/getSecurityCode.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
истинное состояние:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'dir/getSecurityCode.php', true); // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);