Estamos trabajando con un marco de interfaz personalizado que se basa en PrimeFaces/JSF.
Recientemente, agregamos una pantalla que muestra cuánto tiempo transcurre hasta que el usuario cierra la sesión debido a la inactividad. Para restablecer correctamente la cuenta regresiva de la actividad del usuario, sobrescribí el método XMLHttpRequest.prototype.send a través de JavaScript:
var minutesUntilTimeout = 60; var logoutAt = minutesUntilTimeout * 60 * 1000 + new Date().getTime(); var send = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(data) { send.call(this, data); logoutAt = minutesUntilTimeout * 60 * 1000 + new Date().getTime(); }Esto funciona correctamente tal como está.
Sin embargo, encontramos un problema: el código JS se ejecuta al cargar la página y, para que funcione correctamente, es obligatorio que XMLHttpRequest.prototype.send contenga la funcionalidad original. Sin embargo, a veces todavía contiene nuestra función sobrescrita de la última ejecución de JS (por ejemplo, cuando llegamos a una página a través del menú de navegación). Esto rompe la aplicación, ya que cada acción del usuario que usa XMLHttpRequest.prototype.send activará la función sobrescrita, que internamente llama a la función var send "original", que es la misma función en este caso especial, creando un bucle infinito. Creo que tiene que ver con la solicitud HTTP, ya que, por lo que recuerdo, las migas de pan usan GET y todos los botones, el menú principal, etc. usan POST (pero esto es solo una suposición, no estoy tan profundo en los detalles de implementación de nuestro marco).
¿Hay alguna forma de garantizar que XMLHttpRequest.prototype se restablezca correctamente en TODOS los cambios de página, además de simplemente evitar las migas de pan?
Una vez más, el principio del patito de goma es cierto: minutos después de la publicación, encontré una solución. En caso de que alguien lo necesite, agregué una diferenciación de casos:
if (typeof XMLHttpRequest.prototype.oldSend !== "function") { XMLHttpRequest.prototype.oldSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(data) { XMLHttpRequest.prototype.oldSend.call(this, data); logoutAt = minutesUntilTimeout * 60 * 1000 + new Date().getTime(); } }