Estou construindo um aplicativo da web com diferentes bibliotecas JS (AngularJS, OpenLayers, ...) e preciso de uma forma de interceptar todas as respostas AJAX para poder, no caso de a sessão do usuário logado expirar (a resposta volta com 401 Unauthorized
status), redirecioná-lo para a página de login.
Eu sei que o AngularJS se oferece interceptors
para gerenciar esses cenários, mas não foi capaz de encontrar uma maneira de conseguir tal injeção nas solicitações do OpenLayers. Então, optei por uma abordagem JS baunilha.
Aqui encontrei este pedaço 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 adaptei e parece que se comporta como esperado (testei apenas no último Google Chrome).
Como ele modifica o protótipo de XMLHTTPRequest, estou me perguntando o quão perigoso isso pode resultar ou se pode produzir sérios problemas de desempenho. E a propósito, haveria alguma alternativa válida?
Atualização: como interceptar solicitações antes de serem enviadas
O truque anterior funciona bem. Mas e se no mesmo cenário você quiser injetar alguns cabeçalhos antes que a solicitação seja enviada? Faça o seguinte:
(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);
fonte
Respostas:
Este tipo de gancho de função é perfeitamente seguro e é feito regularmente em outros métodos por outros motivos.
E o único impacto no desempenho é realmente apenas uma chamada de função extra para cada um,
.open()
mais qualquer código que você mesmo execute, o que provavelmente é irrelevante quando uma chamada de rede está envolvida.No IE, isso não detectará nenhum código que tente usar o
ActiveXObject
método de controle de fazer Ajax. Um código bem escrito procura primeiro peloXMLHttpRequest
objeto e o usa, se disponível, e está disponível desde o IE 7. Mas, pode haver algum código que usa oActiveXObject
método se estiver disponível, o que seria verdadeiro em versões muito posteriores do IE.Em navegadores modernos, existem outras maneiras de emitir chamadas Ajax, como a
fetch()
interface, portanto, se alguém estiver procurando conectar todas as chamadas Ajax, será necessário conectar mais do que apenasXMLHttpRequest
.fonte
fetch()
função para interceptar todas as chamadas para ela - embora eu nunca tenha tentado isso. Parece que este módulo faz isso.comment_service_ajax
solicitações.Isso não capturará XMLHttpRequests para algumas versões do IE (9 e abaixo) . Dependendo da biblioteca, eles podem procurar o controle ActiveX proprietário do IE primeiro.
E, claro, todas as apostas estão canceladas se você estiver usando um DOCTYPE não estrito no IE, mas tenho certeza que você sabia disso.
Referência: CanIuse
fonte
Como gentilmente apontado pelo Firefox AMO Editor
Rob W
,...
E aqui está um link de referência:
https://xhr.spec.whatwg.org/#the-open()-method
fonte