CORS: pasa la verificación previa, la solicitud principal se completa con 200, pero el navegador aún tiene un error de origen

Estoy enviando una solicitud ajax CORS a un servidor de nodo que ejecuta Express. Tanto en los registros del servidor como en la consola js, puedo ver que la solicitud de OPCIONES de verificación previa se realiza correctamente.

Entonces, la solicitud principal también tiene éxito en el servidor y responde con un 200 y creo que son los encabezados correctos. Sin embargo, en Chrome, la pestaña de redes informa que la última solicitud está “cancelada” y la respuesta no se acepta o procesa:

XMLHttpRequest no puede cargar http://myserver.com/upload . Origin http://mysite.com no está permitido por Access-Control-Allow-Origin.

Aquí están los registros del servidor con los encabezados impresos para solicitudes y respuestas:

76.79.201.210 - - [27/Jun/2013:23:23:17 +0000] "OPTIONS /upload HTTP/1.1" 204 0 "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36" START { host: 'localhost:5001', connection: 'close', 'content-length': '109587', origin: 'http://mysite.com', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36', 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryBZA4TATeeVWMHArH', accept: '*/*', referer: 'http://mysite.com/add', 'accept-encoding': 'gzip,deflate,sdch', 'accept-language': 'en-US,en;q=0.8' } { 'x-powered-by': 'Express', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS', 'access-control-allow-headers': 'X-Requested-With' } XX.XX.XXX.210 - - [27/Jun/2013:23:23:19 +0000] "POST /upload HTTP/1.1" 200 118 "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36" - - - [Thu, 27 Jun 2013 23:23:19 GMT] "POST /upload HTTP/1.0" 200 - "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36" 

Actualización: captura de pantalla de la pestaña de la red de Chrome – la “cancelada” es la que estaba arriba 200

Screen Shot 2013-06-27 at 5.25.25 PM.png

Solución de problemas relacionados con CORS

  • Si está intentando reproducir el problema y no está viendo una solicitud / respuesta, es posible que su navegador haya guardado un bash de solicitud de verificación previa fallido . Borrar la memoria caché de su navegador también puede borrar la memoria caché de verificación previa …

https://developers.google.com/storage/docs/cross-origin

Probé la siguiente configuración en test-cors.org y parece funcionar. Solo recuerda limpiar tu caché de vez en cuando mientras estás resolviendo problemas.

 var allowedHost = { // this is the origin that test-cors.org uses 'http://client.cors-api.appspot.com': true }; var allowCrossDomain = function(req, res, next) { if (!req.headers.origin || allowedHost[req.headers.origin]) { res.header('Access-Control-Allow-Credentials', true); res.header('Access-Control-Allow-Origin', req.headers.origin) res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); res.header('Access-Control-Allow-Headers', 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'); if (req.method == 'OPTIONS') res.send(200); else next(); } else { res.send(403, { auth: false }); } } 

¡Buena suerte!

Así que resulta que debido a que tanto nginx como express estaban configurados para responder con encabezados a la solicitud de opciones, de alguna manera estaba combinando el valor del encabezado Access-Control-Allow-Origin en ” “, “ “. No sé si lo leyó como una matriz o qué.

Todavía bastante desconcertado porque 1) ¿Por qué la solicitud superó a nginx? y 2) ¿Por qué el navegador prosiguió con la POST si los encabezados de OPCIONES estaban desordenados?

Oh bueno, la lección, como siempre, no te repitas.