Я пытаюсь сделать запрос на отправку 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
заголовком)
javascript
jquery
xmlhttprequest
cors
Магматический
источник
источник
Ответы:
ОБНОВЛЕНИЕ: как указал 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-requested-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); }
источник
Другая возможность заключается в том, что настройка
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'
источник
application/x-www-form-urlencoded
и eventext/plain
. И я попытался добавить заголовок ответаAccess-Control-Allow-Methods "POST, GET, OPTIONS"
Ничего не сработало.dataType
влияет наAccept
заголовок запроса, но не наContent-Type
заголовок запроса.Вы отправляете «параметры» в 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
Обновление : я искал в Google на основе ответа monsur, и я обнаружил, что вам нужно добавить
Access-Control-Allow-Headers: Content-Type
(ниже полный абзац)http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/
источник
var data = {action:"something"}
jQuery.ajaxSetup({'beforeSend': function(xhr) {xhr.setRequestHeader(string, string)}})
и воспроизведения различных отправленных заголовков (пример для рельсов здесь: railscasts.com/episodes/136-jquery )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", "*");
источник
Измените свой JQuery следующим образом:
$.ajax({ url: someurl, contentType: 'application/json', data: JSONObject, headers: { 'Access-Control-Allow-Origin': '*' }, //add this line dataType: 'json', type: 'POST', success: function (Data) {....} });
источник
contentType: 'application/json', data: JSONObject,
- Сервер не ожидает JSON, поэтому отправка JSON не имеет смысла. Также не существует такой вещи, как объект JSON .headers: { 'Access-Control-Allow-Origin': '*' }, //add this line
- Никогда не делай этого.Access-Control-Allow-Origin
это заголовок ответа , а не заголовок запроса. В лучшем случае это ничего не даст. В худшем случае он преобразует запрос из простого в предварительный, что усложняет работу на сервере.