AJAX en Chrome enviando OPCIONES en lugar de GET / POST / PUT / DELETE?

Estoy trabajando en una aplicación web interna en el trabajo. En IE10, las solicitudes funcionan bien, pero en Chrome todas las solicitudes de AJAX (que son muchas) se envían utilizando OPTIONS en lugar de cualquier método definido que le dé. Técnicamente, mis solicitudes son “dominio cruzado”. El sitio se publica en localhost: 6120 y el servicio al que estoy haciendo las solicitudes de AJAX está en 57124. Este error de jquery cerrado define el problema, pero no es una solución real.

¿Qué puedo hacer para usar el método http correcto en las solicitudes ajax?

Editar:

Esto está en la carga de documentos de cada página:

jQuery.support.cors = true; 

Y cada AJAX se construye de manera similar:

 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" }); 

Chrome está realizando una verificación previa de la solicitud para buscar encabezados CORS . Si la solicitud es aceptable, enviará la solicitud real. Si está haciendo este dominio cruzado, simplemente tendrá que lidiar con él o, de lo contrario, encontrará una manera de hacer que la solicitud no sea de dominio cruzado. Esta es la razón por la cual el error jQuery se cerró como no se solucionó. Esto es por diseño.

A diferencia de las solicitudes simples (discutidas anteriormente), las solicitudes “preluminadas” primero envían una solicitud HTTP por el método OPCIONES al recurso en el otro dominio, para determinar si la solicitud real es segura de enviar. Las solicitudes entre sitios se preludian de esta manera, ya que pueden tener implicaciones para los datos del usuario. En particular, una solicitud se realiza de antemano si:

  • Utiliza métodos distintos de GET, HEAD o POST. Además, si se utiliza POST para enviar datos de solicitud con un tipo de contenido distinto de application / x-www-form-urlencoded, multipart / form-data o text / plain, por ejemplo, si la solicitud POST envía una carga XML al servidor usando application / xml o text / xml, entonces la solicitud se realiza de antemano.
  • Establece encabezados personalizados en la solicitud (por ejemplo, la solicitud utiliza un encabezado como X-PINGOTHER)

En función del hecho de que la solicitud no se envía en el puerto predeterminado 80/443, esta llamada Ajax se considera automáticamente una solicitud de recurso de origen cruzado (CORS) , lo que significa que la solicitud emite automáticamente una solicitud de OPCIONES que verifica Cabeceras CORS en el lado del servidor / servlet.

Esto sucede incluso si configura

 crossOrigin: false; 

o incluso si lo haces.

La razón es simplemente que localhost != localhost:57124 . Intente enviarlo solo al localhost sin el puerto: fallará, porque el objective solicitado no será accesible, sin embargo , tenga en cuenta que si los nombres de dominio son iguales, la solicitud se envía sin la solicitud de OPCIONES antes del POST.

Estoy de acuerdo con Kevin B, el informe de errores lo dice todo. Parece que estás intentando hacer llamadas ajax de dominios cruzados. Si no está familiarizado con la misma política de origen, puede comenzar aquí: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript .

Si esto no pretende ser una llamada ajax entre dominios, intente hacer que su url objective sea relativa y vea si el problema desaparece. Si estás realmente desesperado mira el JSONP, pero ten cuidado, el caos acecha. Realmente no hay mucho más que podamos hacer para ayudarte.

Si es posible, pase los parámetros a través de GET / POST regular con un nombre diferente y deje que el código del lado del servidor lo maneje.

Tuve un problema similar con mi propio proxy para eludir CORS y obtuve el mismo error de POST-> OPTION en Chrome. Era el encabezado Authorization en mi caso ( "x-li-format" y "X-UserName" aquí en tu caso). Terminé pasándolo en un formato ficticio (por ejemplo, AuthorizatinJack en GET) y cambié el código para mi proxy para convertirlo en un encabezado al hacer la llamada al destino. Aquí está en PHP:

 if (isset($_GET['AuthorizationJack'])) { $request_headers[] = "Authorization: Basic ".$_GET['AuthorizationJack']; } 

En mi caso, estoy llamando a una API alojada por AWS (API Gateway). El error ocurrió cuando intenté llamar a la API desde un dominio que no era el dominio propio de la API. Como soy el propietario de la API, habilité CORS para el entorno de prueba, como se describe en la Documentación de Amazon .

En producción, este error no ocurrirá, ya que la solicitud y la API estarán en el mismo dominio.

¡Espero que ayude!

Como respondió @Dark Falcon, simplemente lo resolví.

En mi caso, estoy usando el servidor node.js y estoy creando una sesión si no existe. Como el método OPTIONS no tiene los detalles de la sesión, terminó creando una nueva sesión para cada solicitud de método POST.

Así que en mi rutina de aplicación para crear-sesión-si-no-existe, acabo de agregar una verificación para ver si el método es OPTIONS , y si es así, simplemente saltee la sesión creando una parte:

  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(); } } 

Las solicitudes “preflighted” primero envían una solicitud HTTP por el método OPTIONS al recurso en el otro dominio, para determinar si la solicitud real es segura de enviar. Solicitudes entre sitios

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Considera usar axios

 axios.get( url, { headers: {"Content-Type": "application/json"} } ).then( res => { if(res.data.error) { } else { doAnything( res.data ) } }).catch(function (error) { doAnythingError(error) }); 

Tuve este problema usando fetch y Axios funcionó perfectamente.

Me he encontrado con un problema muy similar. Pasé casi medio día para entender por qué todo funciona correctamente en Firefox y falla en Chrome. En mi caso fue debido a campos duplicados (o quizás mal escritos) en mi encabezado de solicitud.