Запрос CORS POST работает с простым javascript, но почему бы не использовать jQuery?
Я пытаюсь сделать запрос на отправку Cross Origin, и я получил его в простом Javascript:
var request = new XMLHttpRequest();
var params = "action=something";
request.open('POST', url, true);
request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");};
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);
Но я хотел бы использовать jQuery, но я не могу заставить его работать. Это то, что я пытаюсь:
$.ajax(url, {
type:"POST",
dataType:"json",
data:{action:"something"},
success:function(data, textStatus, jqXHR) {alert("success");},
error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});
Это приводит к ошибке. Если кто-нибудь знает, почему jQuery не работает, сообщите нам об этом. Спасибо.
(Я использую jQuery 1.5.1 и Firefox 4.0, и мой сервер отвечает правильным заголовком Access-Control-Allow-Origin)
Ответы
Ответ 1
ОБНОВЛЕНИЕ: Как указывал TimK, это не требуется с jquery 1.5.2. Но если вы хотите добавить пользовательские заголовки или разрешить использование учетных данных (имя пользователя, пароль или файлы cookie и т.д.), Читайте дальше.
Думаю, я нашел ответ! (4 часа и много проклятий позже)
//This does not work!!
Access-Control-Allow-Headers: *
Вам нужно вручную указать все заголовки, которые вы примете (по крайней мере, это было для меня в FF 4.0 и Chrome 10.0.648.204).
Метод jQuery $.ajax отправляет заголовок "x-request-with" для всех запросов на междоменные запросы (я думаю, что это единственный кросс-домен).
Таким образом, отсутствующий заголовок, необходимый для ответа на запрос OPTIONS:
//no longer needed as of jquery 1.5.2
Access-Control-Allow-Headers: x-requested-with
Если вы передаете любые "простые" заголовки, вам нужно будет включить их в свой список (я пришлю еще один):
//only need part of this for my custom header
Access-Control-Allow-Headers: x-requested-with, x-requested-by
Итак, чтобы собрать все вместе, вот мой PHP:
// * wont work in FF w/ Allow-Credentials
//if you dont need Allow-Credentials, * seems to work
header('Access-Control-Allow-Origin: http://www.example.com');
//if you need cookies or login etc
header('Access-Control-Allow-Credentials: true');
if ($this->getRequestMethod() == 'OPTIONS')
{
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Max-Age: 604800');
//if you need special headers
header('Access-Control-Allow-Headers: x-requested-with');
exit(0);
}
Ответ 2
Другая возможность заключается в том, что установка dataType: json
заставляет JQuery отправлять заголовок Content-Type: application/json
. Это считается нестандартным заголовком CORS и требует запроса предварительной проверки CORS. Итак, несколько вещей, чтобы попробовать:
1) Попробуйте настроить сервер для отправки правильных ответов перед полетом. Это будет в виде дополнительных заголовков, таких как Access-Control-Allow-Methods
и Access-Control-Allow-Headers
.
2) Снимите настройку dataType: json
. JQuery должен запросить Content-Type: application/x-www-form-urlencoded
по умолчанию, но, чтобы быть уверенным, вы можете заменить dataType: json
на contentType: 'application/x-www-form-urlencoded'
Ответ 3
Вы отправляете "параметры" в js:
request.send(params);
но "данные" в jquery ". Определены ли данные?: data:data,
Кроме того, у вас есть ошибка в URL-адресе:
$.ajax( {url:url,
type:"POST",
dataType:"json",
data:data,
success:function(data, textStatus, jqXHR) {alert("success");},
error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});
Вы смешиваете синтаксис с параметром $.post
Обновление. Я искал поисковые запросы на основе ответа monsur, и я обнаружил, что вам нужно добавить Access-Control-Allow-Headers: Content-Type
(ниже полный абзац)
http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/
Как работает CORS
CORS работает очень похоже на Flash файл crossdomain.xml. В основном, браузер отправит кросс-домен запрос к службе, настройка HTTP заголовок Происхождение к запрашивающему сервер. Услуга включает в себя несколько заголовки вроде Access-Control-Allow-Origin для указать, является ли такой запрос допускается.
Для менеджеров соединений BOSH это достаточно, чтобы указать, что все происхождение допускаются, устанавливая значение Access-Control-Allow-Origin - *. Заголовок Content-Type также должен быть белый, перечисленных в Заголовок Access-Control-Allow-Headers.
Наконец, для некоторых типов запросы, включая соединение BOSH запросы менеджера, разрешения проверка будет проведена до начала полета. браузер выполнит запрос OPTIONS и ожидать возврата некоторых HTTP-заголовков которые указывают, какие разрешены, какие методы разрешены, и как долго это разрешение будет последний. Например, вот что Пенджаб и ejabberd патчи Я сделал return for OPTIONS:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
Ответ 4
Cors меняет метод запроса, прежде чем это сделано, с POST на OPTIONS, поэтому ваши данные не будут отправлены. Способ, который работал для решения этой проблемы cors, - выполнение запроса с помощью ajax, который не поддерживает метод OPTIONS. пример кода:
$.ajax({
type: "POST",
crossdomain: true,
url: "http://localhost:1415/anything",
dataType: "json",
data: JSON.stringify({
anydata1: "any1",
anydata2: "any2",
}),
success: function (result) {
console.log(result)
},
error: function (xhr, status, err) {
console.error(xhr, status, err);
}
});
с этими заголовками на сервере С#:
if (request.HttpMethod == "OPTIONS")
{
response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
response.AddHeader("Access-Control-Max-Age", "1728000");
}
response.AppendHeader("Access-Control-Allow-Origin", "*");
Ответ 5
Измените ваш Jquery следующим образом:
$.ajax({
url: someurl,
contentType: 'application/json',
data: JSONObject,
headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
dataType: 'json',
type: 'POST',
success: function (Data) {....}
});