javascript - missing - CORS Pre-Flight regresa con Access-Control-Allow-Origin:*, el navegador aún falla la solicitud
cors javascript (6)
Activar un AJAX GET
para http://qualifiedlocalhost:8888/resource.json
inicia el esperado vuelo previo de CORS, que parece que vuelve correctamente:
Solicitud de OPTIONS
pre-vuelo
Request URL:http://qualifiedlocalhost:8888/resource.json
Request Method:OPTIONS
Status Code:200 OK
Encabezados de solicitud
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, origin, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:qualifiedlocalhost:8888
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
Cabeceras de respuesta
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:2
Content-Type:text/plain
Date:Thu, 01 Aug 2013 19:57:43 GMT
Set-Cookie:connect.sid=s%3AEpPytDm3Dk3H9V4J9y6_y-Nq.Rs572s475TpGhCP%2FK%2B2maKV6zYD%2FUg425zPDKHwoQ6s; Path=/; HttpOnly
X-Powered-By:Express
¿Luciendo bien?
Entonces debería funcionar, ¿verdad?
Pero la solicitud posterior aún falla con el error XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
Verdadera solicitud
Request URL:http://qualifiedlocalhost:8888/resource.json
Encabezados de solicitud
Accept:application/json, text/plain, */*
Cache-Control:no-cache
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
X-Requested-With:XMLHttpRequest
¡Ayuda!
Tal vez está mirando justo delante de mí. Pero, ¿alguna idea? En caso de que sea relevante ... estoy usando un $resource
AngularJS $resource
y hablando con un servidor CompoundJS.
¿Su servidor web / función de obtención TAMBIÉN incluye el encabezado HTTP: Access-Control-Allow-Origin? Eventualmente encontré el éxito con esa adición, utilizando AngularJS 1.0.7 y un servlet de Java remoto. Aquí está mi fragmento de código Java: no se requirieron cambios en el cliente AngularJS:
Servlet:
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Send Response
super.doOptions(request, response);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* ... */
response.setHeader("Access-Control-Allow-Origin", "*");
}
Una alternativa más elegante es un filtro servlet.
Hace poco tuve el mismo problema . El problema es que el encabezado Access-Control-Allow-Origin
(y, si lo usa, el encabezado Access-Control-Allow-Credentials
) debe enviarse tanto en la respuesta de verificación previa como en la respuesta real.
Tu ejemplo lo tiene solo en la respuesta previa al vuelo.
Hemos estado notando el mismo problema, donde el servidor está enviando los encabezados CORS correctos, pero el navegador falla porque cree que no se cumplen los requisitos de CORS. Más interesante, en nuestro caso, solo sucede en algunas llamadas AJAX en la misma sesión del navegador, pero no en todas.
Teoría del trabajo ...
Borrar el caché del navegador resuelve el problema en nuestro caso: mi teoría de trabajo actual es que esto tiene algo que ver con las cookies establecidas por el servidor de origen cruzado. Noté que en su escenario, se está configurando una cookie como parte de la respuesta a la solicitud de OPCIONES previas al vuelo. ¿Ha intentado hacer que el servidor no establezca cookies para solicitudes provenientes de un origen diferente?
Sin embargo, hemos notado que en algunos casos, el problema reapareció después de reiniciar el navegador. Además, ejecutar el navegador en modo privado hace que el problema desaparezca, apuntando a algún problema relacionado con lo que hay en el caché del navegador.
Para referencia, aquí está mi escenario (casi lo publiqué como una nueva pregunta en SO, pero lo puse aquí en su lugar):
Nos encontramos con un error en el que fallaron algunas solicitudes CORS GET realizadas a través de jQuery.ajax. En una sesión de navegador dada, vemos que se realiza la solicitud de OPCIONES previas al vuelo, seguida de la solicitud real. En la misma sesión, algunas solicitudes pasan y otras fallan.
La secuencia de solicitudes y respuestas en la consola de red del navegador es la siguiente:
Primero las OPCIONES previa a la solicitud de vuelo.
OPTIONS /api/v1/users/337/statuses
HTTP/1.1 Host: api.obfuscatedserver.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://10.10.8.84:3003
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Access-Control-Request-Headers: accept, origin, x-csrf-token, auth
Accept: */* Referer: http://10.10.8.84:3003/
Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8
Que recibe una respuesta como,
HTTP/1.1 200 OK
Date: Tue, 06 Aug 2013 19:18:22 GMT
Server: Apache/2.2.22 (Ubuntu)
Access-Control-Allow-Origin: http://10.10.8.84:3003
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Max-Age: 1728000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, origin, x-csrf-token, auth
X-UA-Compatible: IE=Edge,chrome=1
Cache-Control: no-cache
X-Request-Id: 4429c4ea9ce12b6dcf364ac7f159c13c
X-Runtime: 0.001344
X-Rack-Cache: invalidate, pass
X-Powered-By: Phusion
Passenger 4.0.2
Status: 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
Entonces la solicitud GET real,
GET https://api.obfuscatedserver.com/api/v1/users/337
HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://10.10.8.84:3003/
Origin: http://10.10.8.84:3003
X-CSRF-Token: xxxxxxx
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
auth: xxxxxxxxx
Que recibe un error en la consola del navegador como,
XMLHttpRequest
cannot load https://api.obfuscatedserver.com/api/v1/users/337.
Origin http://10.10.8.84:3003 is not allowed by Access-Control-Allow-Origin.
Depuración adicional
Puedo reproducir la misma secuencia a través de curl, y veo respuestas válidas provenientes del servidor. es decir, tienen los encabezados CORS esperados que deberían permitir que las solicitudes se procesen.
Ejecutar el mismo escenario en una ventana del navegador en privado / de incógnito no reproduce el problema. Esto me llevó a intentar borrar el caché, y eso hizo que el problema desapareciera también. Pero después de un tiempo, volvió.
El problema se reproducía en el safari del iPhone y en Chrome en el escritorio de OSX.
Lo que realmente necesito ayuda con
Sospecho que hay algunas cookies configuradas en el dominio de origen cruzado que se están involucrando aquí y potencialmente exponen un error en el navegador. ¿Hay herramientas o puntos de interrupción que puedo establecer en el navegador (pila nativa) para intentar depurar esto más? Un punto de interrupción en el código que evalúa la política CORS sería ideal.
Parece que su respuesta a ''opciones'' está funcionando bien. El problema parece estar en la respuesta ''obtener''.
Querrá que su respuesta ''obtener'' devuelva los mismos encabezados CORS que la respuesta ''opciones''.
En particular, la respuesta ''get'' debería incluir
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
Usa el módulo cors para evitar el problema.
var cors = require(''cors'')
var app = express()
app.use(cors())
cambie sus métodos de acceso-control-permiso: ''GET, POST'' a ''GET, POST, PUT, DELETE''
antes de:
app.use(function(req, res, next) {
res.setHeader(''Access-Control-Allow-Origin'', ''*'');
res.setHeader(''Access-Control-Allow-Methods'', ''GET, POST'');
res.setHeader(''Access-Control-Allow-Headers'', ''X-Requested-With,content-type, Authorization'');
next();
});
Después:
app.use(function(req, res, next) {
res.setHeader(''Access-Control-Allow-Origin'', ''*'');
res.setHeader(''Access-Control-Allow-Methods'', ''GET, POST, PUT ,DELETE'');
res.setHeader(''Access-Control-Allow-Headers'', ''X-Requested-With,content-type, Authorization'');
next();
});