AJAX в Chrome отправляет OPTIONS вместо GET/POST/PUT/DELETE?
Я работаю над внутренним веб-приложением на работе. В IE10 запросы работают нормально, но в Chrome все запросы AJAX (которых их много) отправляются с помощью OPTIONS вместо того, что я дал этому методу. Технически мои запросы - это "перекрестный домен". Сайт обслуживается на localhost: 6120, а служба, с которой я делаю запросы AJAX, находится на 57124. Эта закрытая ошибка jquery определяет проблему, но не является реальным исправлением.
Что я могу сделать, чтобы использовать правильный метод http в запросах ajax?
Edit:
Это в загрузке документа на каждой странице:
jQuery.support.cors = true;
И каждый AJAX построен аналогично:
var url = 'http://localhost:57124/My/Rest/Call';
$.ajax({
url: url,
dataType: "json",
data: json,
async: true,
cache: false,
timeout: 30000,
headers: { "x-li-format": "json", "X-UserName": userName },
success: function (data) {
// my success stuff
},
error: function (request, status, error) {
// my error stuff
},
type: "POST"
});
Ответы
Ответ 1
В Chrome предваряется запрос на поиск заголовков CORS. Если запрос является приемлемым, он отправит реальный запрос. Если вы выполняете этот кросс-домен, вам просто придется иметь дело с ним или найти способ сделать запрос не междоменным. Вот почему ошибка jQuery была закрыта как не исправлена. Это по дизайну.
В отличие от простых запросов (см. выше), сначала запрашиваются "предполненные" запросы отправьте HTTP-запрос методом OPTIONS на ресурс на другого домена, чтобы определить, является ли фактический запрос безопасным отправлять. Запросы межсайтовых запросов предваряются таким образом, поскольку они могут имеют последствия для пользовательских данных. В частности, запрос предваряется, если:
- Он использует методы, отличные от GET, HEAD или POST. Кроме того, если POST используется для отправки данных запроса с помощью Content-Type, кроме application/x-www-form-urlencoded, multipart/form-data или text/plain, например если запрос POST отправляет полезную нагрузку XML на сервер, используя application/xml или text/xml, тогда запрос предваряется.
- Он устанавливает пользовательские заголовки в запросе (например, запрос использует заголовок, например X-PINGOTHER)
Ответ 2
Исходя из того, что запрос не отправляется на порт 80/443 по умолчанию, этот вызов Ajax автоматически считается запросом ресурса кросс-исходного кода (CORS), что означает, что запрос автоматически выдает запрос OPTIONS, который проверяет заголовки CORS на стороне сервера/сервлета.
Это происходит, даже если вы установили
crossOrigin: false;
или даже если вы опустите его.
Причина в том, что localhost != localhost:57124
. Попробуйте отправить его только на localhost
без порта - он не сработает, потому что запрошенная цель не будет достижима, однако заметьте, что если имена доменов равны, запрос отправляется без запроса OPTIONS перед POST.
Ответ 3
Я согласен с Кевином Б, в отчете об ошибке говорится все. Похоже, вы пытаетесь сделать междоменные аякс-вызовы. Если вы не знакомы с той же политикой происхождения, вы можете начать здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript.
Если это не предназначено для межзадачного вызова ajax, попробуйте сделать свой целевой URL-адрес и посмотреть, не исчезла ли проблема. Если вы действительно отчаянно смотрите на JSONP, но будьте осторожны, хаос скрывается. На самом деле мы не можем сделать больше, чтобы помочь вам.
Ответ 4
Если возможно передать параметры через обычный GET/POST с другим именем и разрешить его код на стороне сервера.
У меня была аналогичная проблема с моим собственным прокси-сервером, чтобы обойти CORS, и я получил ту же ошибку POST- > OPTION в Chrome. Это был заголовок Authorization
в моем случае ("x-li-format"
и "X-UserName"
здесь в вашем случае.) Я закончил передачу его в фиктивном формате (например, AuthorizatinJack
в GET), и я изменил код для своего прокси-сервера превратите это в заголовок при совершении вызова в пункт назначения. Здесь он находится в PHP:
if (isset($_GET['AuthorizationJack'])) {
$request_headers[] = "Authorization: Basic ".$_GET['AuthorizationJack'];
}
Ответ 5
В моем случае я вызываю API, размещенный AWS (API Gateway). Ошибка произошла, когда я попытался вызвать API из домена, отличного от собственного домена API. Поскольку я являюсь владельцем API, я включил CORS для тестовой среды, как описано в Amazon Documentation.
В производстве эта ошибка не произойдет, так как запрос и api будут в одном домене.
Надеюсь, это поможет!
Ответ 6
Как ответил от @Dark Falcon, я просто справился с этим.
В моем случае я использую сервер node.js и создаю сеанс, если он не существует. Поскольку метод OPTIONS не содержит сведений о сеансе, он создал новый сеанс для каждого запроса метода POST.
Итак, в моей программе приложения для создания-сессии-если-не существует, я просто добавил проверку, чтобы проверить, есть ли метод OPTIONS
, и если да, просто пропустите часть создания сеанса:
app.use(function(req, res, next) {
if (req.method !== "OPTIONS") {
if (req.session && req.session.id) {
// Session exists
next();
}else{
// Create session
next();
}
} else {
// If request method is OPTIONS, just skip this part and move to the next method.
next();
}
}
Ответ 7
"предварительно запрограммированные" запросы сначала отправляют HTTP-запрос методом OPTIONS к ресурсу в другом домене, чтобы определить, безопасно ли отправлять фактический запрос. Межсайтовые запросы
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Ответ 8
Рассмотрим использование axios
axios.get( url,
{ headers: {"Content-Type": "application/json"} } ).then( res => {
if(res.data.error) {
} else {
doAnything( res.data )
}
}).catch(function (error) {
doAnythingError(error)
});
У меня была эта проблема, используя fetch, и аксиомы работали отлично.
Ответ 9
Я столкнулся с очень похожей проблемой. Я потратил почти полдня, чтобы понять, почему все работает правильно в Firefox и не работает в Chrome. В моем случае это было из-за дублированных (или, возможно, опечаток) полей в заголовке моего запроса.
Ответ 10
$.ajax({
url: '###',
contentType: 'text/plain; charset=utf-8',
async: false,
xhrFields: {
withCredentials: true,
crossDomain: true,
Authorization: "Bearer ...."
},
method: 'POST',
data: JSON.stringify( request ),
success: function (data) {
console.log(data);
}
});
contentType: 'text/plain; charset = utf-8 ', или просто contentType:' text/plain ', работает для меня!
С уважением!!