ajax - ejemplos - post javascript
¿Por qué el navegador no está configurando cookies después de que se devuelve una solicitud AJAX? (3)
Estoy haciendo una solicitud de ajax usando $ .ajax. La respuesta tiene Set-Cookie
encabezado Set-Cookie
(lo he verificado en las herramientas de desarrollo de Chrome). Sin embargo, ¡el navegador no configura la cookie después de recibir la respuesta! Cuando navego a otra página dentro de mi dominio, la cookie no se envía. (Nota: no estoy haciendo ninguna solicitud ajax entre dominios, la solicitud está en el mismo dominio que el documento).
¿Qué me estoy perdiendo?
EDITAR : Aquí está el código para mi solicitud de Ajax:
$.post(''/user/login'', JSON.stringify(data));
Aquí está la solicitud, como se muestra en las herramientas de desarrollo de Chrome:
Request URL:https://192.168.1.154:3000/user/login
Request Method:POST
Status Code:200 OK
Request Headers:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:35
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
DNT:1
Host:192.168.1.154:3000
Origin:https://192.168.1.154:3000
Referer:https://192.168.1.154:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
X-Requested-With:XMLHttpRequest
Form Data:
{"UserId":"blah","Password":"blah"}:
Respuesta:
Response Headers:
Content-Length:15
Content-Type:application/json; charset=UTF-8
Date:Sun, 16 Mar 2014 03:25:24 GMT
Set-Cookie:SessionId=MTM5NDk0MDMyNHxEdi1CQkFFQ180SUFBUkFCRUFBQVRfLUNBQUVHYzNSeWFXNW5EQXNBQ1ZObGMzTnBiMjVKWkFaemRISnBibWNNTGdBc1ZFcDNlU3RKVFdKSGIzQlNXRkkwVjJGNFJ6TlRVSHA0U0ZJd01XRktjMDF1Y1c1b2FGWXJORzV4V1QwPXwWf1tz-2Fy_Y4I6fypCzkMJyYxhgM3LjVHGAlKyrilRg==; HttpOnly
La answer de @tomkirk no se me aplicaba porque
- No uso la API de
fetch
- Estaba haciendo solicitudes entre sitios (es decir, CORS)
Pero la respuesta me ayudó a dar estos pasos:
fetch
las https://github.com/github/fetch#sending-cookies API CORS API https://github.com/github/fetch#sending-cookies para enviar y recibir cookies
Para solicitudes CORS, use el valor "incluir" para permitir el envío de credenciales a otros dominios:
fetch(''https://example.com:1234/users'', { credentials: ''include'' })
... Para optar por aceptar cookies del servidor, debe usar la opción de credenciales.
{credentials:''include''}
solo establece xhr.withCredentials=true
if (request.credentials === ''include'') { xhr.withCredentials = true }
Tan xhr.withCredentials=true es la parte importante.
Si está utilizando jQuery, puede establecer conCredentials usando $.ajaxSetup(...)
$.ajaxSetup({ crossDomain: true, xhrFields: { withCredentials: true } });
En cuanto a la solicitud, cuando xhr.withCredentials=true
; el encabezado Cookie es enviado
Antes de cambiar xhr.withCredentials=true
- Pude ver el nombre y el valor de Set-Cookie en la respuesta, pero la pestaña "Aplicación" de Chrome en Developer Tools me mostró el nombre y un valor vacío
- Las solicitudes posteriores no enviaron un encabezado de solicitud de
Cookie
.
Después del cambio xhr.withCredentials=true
- Pude ver el nombre de la cookie y el valor de la cookie en la pestaña "Aplicación" de Chrome (un valor consistente con el encabezado Set-Cookie).
- Las solicitudes posteriores enviaron un encabezado de solicitud de
Cookie
con el mismo valor, por lo que mi servidor me trató como "autenticado"
En cuanto a la respuesta: el servidor puede necesitar ciertos encabezados de Access-Control- *
Por ejemplo, configuré mi servidor para devolver estos encabezados:
- Access-Control-Allow-Credentials: cierto
- Access-Control-Allow-Origin: https: // {su-origen}: {su-puerto}
Hasta que hice este cambio del lado del servidor a los encabezados de respuesta, Chrome registró errores en la consola como
Error al cargar
https://{saml-domain}/saml-authn
: la directiva CORS ha bloqueado el redireccionamiento desdehttps://{saml-domain}/saml-redirect
:El valor del encabezado
''Access-Control-Allow-Credentials''
en la respuesta es''''
que debe ser''true''
cuando el modo de credenciales de la solicitud es''include''
. Origenhttps://{your-domain}
por lo tanto, no se permite el acceso.El modo de credenciales de las solicitudes iniciadas por XMLHttpRequest está controlado por el atributo withCredentials.
Después de cambiar este encabezado de Access- *, Chrome no registró errores; el navegador me permite verificar las respuestas autenticadas para todas las solicitudes posteriores.
OK, entonces finalmente descubrí el problema. Resulta que establecer la opción de Path
es importante cuando se envían cookies en una solicitud de AJAX. Si establece Path=/
, por ejemplo:
Set-Cookie:SessionId=foo; Path=/; HttpOnly
... entonces el navegador configurará la cookie cuando navegue a una página diferente. Sin configurar Path
, el navegador utiliza la ruta "predeterminada". Aparentemente, la ruta predeterminada para una cookie establecida por una solicitud AJAX es diferente de la ruta predeterminada utilizada cuando navega a una página directamente. Estoy usando Go / Martini, así que en el lado del servidor hago esto:
session.Options(session.Options{HttpOnly: true, Path:"/"})
Supongo que Python / Ruby / etc. tener un mecanismo similar para establecer Path
.
Ver también: problema de cookies en PHP y AJAX
Si está utilizando la nueva API de fetch
, puede intentar incluir credentials
:
fetch(''/users'', {
credentials: ''same-origin''
})
Eso es lo que me solucionó.
En particular, usando el polyfill: https://github.com/github/fetch#sending-cookies