Estoy construyendo una aplicación web con diferentes bibliotecas JS (AngularJS, OpenLayers, ...) y necesito una forma de interceptar todas las respuestas AJAX para poder, en caso de que la sesión del usuario registrado expire (la respuesta vuelve con el 401 Unauthorized
estado), redirigirlo a la página de inicio de sesión.
Sé que AngularJS ofrece interceptors
administrar tales escenarios, pero no pude encontrar una manera de lograr dicha inyección en las solicitudes de OpenLayers. Así que opté por un enfoque JS vainilla.
Aquí encontré este fragmento de código ...
(function(open) {
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
this.addEventListener("readystatechange", function() {
console.log(this.readyState); // this one I changed
}, false);
open.call(this, method, url, async, user, pass);
};
})(XMLHttpRequest.prototype.open);
... que adapté y parece que se comporta como se esperaba (solo lo probé en el último Google Chrome).
Como modifica el prototipo de XMLHTTPRequest, me pregunto qué tan peligroso podría resultar esto o si podría producir serios problemas de rendimiento. Y, por cierto, ¿habría alguna alternativa válida?
Actualización: cómo interceptar solicitudes antes de que se envíen
El truco anterior funciona bien. Pero, ¿qué pasa si en el mismo escenario desea inyectar algunos encabezados antes de que se envíe la solicitud? Haz lo siguiente:
(function(send) {
XMLHttpRequest.prototype.send = function(data) {
// in this case I'm injecting an access token (eg. accessToken) in the request headers before it gets sent
if(accessToken) this.setRequestHeader('x-access-token', accessToken);
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);
fuente
Respuestas:
Este tipo de función de enganche es perfectamente seguro y se realiza regularmente en otros métodos por otras razones.
Y, el único impacto en el rendimiento es realmente solo una llamada de función adicional por cada
.open()
más el código que ejecute usted mismo, lo que probablemente sea irrelevante cuando se trata de una llamada de red.En IE, esto no detectará ningún código que intente usar el
ActiveXObject
método de control para hacer Ajax. El código bien escrito busca primero elXMLHttpRequest
objeto y lo usa si está disponible y ha estado disponible desde IE 7. Pero, podría haber algún código que use elActiveXObject
método si está disponible, lo que sería cierto en versiones mucho más recientes de IE.En los navegadores modernos, hay otras formas de emitir llamadas Ajax, como la
fetch()
interfaz, por lo que si uno está buscando conectar todas las llamadas Ajax, debe conectar más que soloXMLHttpRequest
.fuente
fetch()
función para interceptar todas las llamadas a ella, aunque nunca lo he intentado. Parece que este módulo hace eso.comment_service_ajax
solicitudes.Esto no detectará XMLHttpRequests para algunas versiones de IE (9 y anteriores) . Dependiendo de la biblioteca, pueden buscar primero el control ActiveX propietario de IE.
Y, por supuesto, todas las apuestas están canceladas si está utilizando un DOCTYPE no estricto en IE, pero estoy seguro de que lo sabía.
Referencia: CanIuse
fuente
Como señaló amablemente el editor AMO de Firefox
Rob W
,...
Y aquí hay un enlace de referencia:
https://xhr.spec.whatwg.org/#the-open()-method
fuente