google chrome - Chrome cancela CORS XHR al redirigir HTTP 302
google-chrome redirect (4)
Encontré útil esta publicación sobre cómo configurar el encabezado CORS de Access-Control-Allow-Origin correcto en su respuesta 302 , al menos en mi caso de sonido similar.
La investigación del problema mostró que su XHR no estaba aterrizando directamente en la URL compatible con CORS, sino que se le redirigía a través de una respuesta HTTP 302 (redirigir).
Tenga en cuenta que la URL de redireccionamiento también debe incluir un encabezado Access-Control-Allow-Origin; de lo contrario, el navegador se detendrá allí con su intento de solicitud entre dominios.
También descubrí que la configuración de encabezados CORS adicionales más allá de Access-Control-Allow-Origin a menudo dará como resultado una transacción cancelada.
Parece que de acuerdo con las solicitudes CORS Spec , GET y POST deben seguir 302 redirecciones de forma transparente. Pero Chrome está cancelando mi solicitud.
Aquí está el JS que hace la solicitud:
var r = new XMLHttpRequest();
r.open(''GET'', ''https://dev.mysite.com/rest'', true);
r.send();
Esto es lo que debería suceder:
- Cliente: XHR POST request to / rest
- Servidor: responde con HTTP 302 redirigir a / descansar /
- Cliente: siga esa redirección
Pero después del paso 2, Chrome cancela la solicitud. Si no hubiera HTTP 302, la solicitud funcionaría perfectamente. He confirmado esto
Cuando se ejecuta la solicitud, puedo ver en el panel de red de Chrome solo un XHR, una solicitud POST cancelada sin encabezados de respuesta ni cuerpo de respuesta.
Depurando con la herramienta interna de red de Chrome, veo que hubo una respuesta enviada por el servidor, y después de eso, la solicitud fue cancelada. Aquí está el resultado de la solicitud:
79295: URL_REQUEST
https://dev.mysite.com/rest
Start Time: 2013-08-30 12:41:11.637
t=1377880871637 [st= 0] +REQUEST_ALIVE [dt=13455]
t=1377880871638 [st= 1] URL_REQUEST_BLOCKED_ON_DELEGATE [dt=1]
--> delegate = "extension Adblock Plus"
t=1377880871639 [st= 2] +URL_REQUEST_START_JOB [dt=13453]
--> load_flags = 143540480 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VERIFY_EV_CERT)
--> method = "POST"
--> priority = 2
--> upload_id = "0"
--> url = "https://dev.mysite.com/rest"
t=1377880871639 [st= 2] HTTP_CACHE_GET_BACKEND [dt=0]
t=1377880871639 [st= 2] +HTTP_STREAM_REQUEST [dt=7]
t=1377880871646 [st= 9] HTTP_STREAM_REQUEST_BOUND_TO_JOB
--> source_dependency = 79296 (HTTP_STREAM_JOB)
t=1377880871646 [st= 9] -HTTP_STREAM_REQUEST
t=1377880871646 [st= 9] +HTTP_TRANSACTION_SEND_REQUEST [dt=0]
t=1377880871646 [st= 9] HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /facultyportfolio-rest HTTP/1.1
Host: dev.liberty.edu
Connection: keep-alive
Content-Length: 46
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36
Content-Type: application/json; charset=UTF-8
Accept: */*
Referer: http://localhost:8080/ajaxtest.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
t=1377880871646 [st= 9] HTTP_TRANSACTION_SEND_REQUEST_BODY
--> did_merge = true
--> is_chunked = false
--> length = 46
t=1377880871646 [st= 9] -HTTP_TRANSACTION_SEND_REQUEST
t=1377880871646 [st= 9] +HTTP_TRANSACTION_READ_HEADERS [dt=1001]
t=1377880871646 [st= 9] HTTP_STREAM_PARSER_READ_HEADERS [dt=1000]
t=1377880872646 [st= 1009] HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 Found
Date: Fri, 30 Aug 2013 16:41:11 GMT
Server: Apache/2
Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Allow-Credentials: true
Location: https://dev.mysite.com/rest/
Content-Language: en-US
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 20
Connection: close
Content-Type: text/plain; charset=UTF-8
t=1377880872647 [st= 1010] -HTTP_TRANSACTION_READ_HEADERS
t=1377880872647 [st= 1010] +URL_REQUEST_BLOCKED_ON_DELEGATE [dt=12445]
t=1377880885091 [st=13454] CANCELLED
t=1377880885092 [st=13455] -URL_REQUEST_START_JOB
--> net_error = -3 (ERR_ABORTED)
t=1377880885092 [st=13455] -REQUEST_ALIVE
Al final, puede ver "Cancelado" debido a "URL_REQUEST_BLOCKED_ON_DELEGATE". No sé lo que eso significa. Pero, de nuevo, si no hubiera redirección HTTP 302, el error no ocurriría.
¿Alguien sabe qué está causando que Chrome cancele esta solicitud?
Las respuestas aquí son mixtas, haciendo alusión a ciertas configuraciones en el código, etc. que pueden resolver el problema de redirección con CORS, pero la especificación CORS especifica claramente cuándo fallarán / pasarán tales redireccionamientos CORS: según la especificación, los navegadores deberían
- Permite la redirección 3XX, si la solicitud al recurso redirigido no requiere verificación previa al vuelo (solicitudes CORS simples sin encabezado personalizado, por ejemplo). Ver https://www.w3.org/TR/cors/#simple-cross-origin-request-0
Si el indicador de redirección manual no está configurado y la respuesta tiene un código de estado HTTP de 301, 302, 303, 307 o 308, aplique los pasos de redireccionamiento
- No permita la redirección de 3XX, si la solicitud de recurso redirigido requiere verificación previa al vuelo. Ver https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
Si la respuesta tiene un código de estado HTTP de 301, 302, 303, 307 o 308, aplique los pasos de error de caché y red.
He explorado varios escenarios de CORS en github repo: https://github.com/monmohan/cors-experiment .
Este problema específico con redirección fallida también se puede reproducir fácilmente de forma aislada por el paquete aquí: https://github.com/monmohan/cors-experiment/tree/master/issue
También tuve el problema de que Chrome no estaba siguiendo una redirección en una solicitud de CORS. Para mí, el problema fue que el JS-framework que uso (Sencha Touch) agrega un encabezado de solicitud: X-Requerido-Con: "XMLHttpRequest"
Tan pronto como eliminé esto (en Sencha Touch llamando a Ext.Ajax.setUseDefaultXhrHeader (false);) funcionó como un amuleto.
No estoy seguro por qué, pero espero que esta información ayude a alguien.
Si el código de estado 302 se recibe en respuesta a una solicitud que no sea GET o HEAD, el agente de usuario NO DEBE redireccionar automáticamente la solicitud a menos que el usuario pueda confirmarla, ya que esto podría cambiar las condiciones bajo las cuales se emitió la solicitud.