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 ', работает для меня! С уважением!!