2016-10-18 1 views
1

J'ai un site au travail qui, lorsqu'il n'est pas connecté, redirige vers la mauvaise page de connexion.La redirection émise par Greasemonkey ne fonctionne que si alert() est appelé après la ligne de redirection

<html> 
    <head> 
    <meta name="robots" content="noindex,nofollow"> 
    <script type="application/javascript"> 
     window.location.href = '/access/login?return_to=' + encodeURIComponent(window.location.href); 
    </script> 
    </head> 
</html> 

La page réelle est chargé avec un 200 OK et sans en-tête Location:.

Pour remédier à cela, je compose un script Greasemonkey à exécuter avant pageload:

// ==UserScript== 
// @name  Fix buggy login redirect 
// @namespace [email protected] 
// @description Fixes the buggy redirect that redirects to the wrong login page 
// @include https://internal.domain/* 
// @version 1 
// @grant  none 
// @run-at document-start 
// ==/UserScript== 
window.addEventListener('beforescriptexecute', function(e) { 
if (document.getElementsByTagName("script")[0].text.trim() === "window.location.href = '/access/login?return_to=' + encodeURIComponent(window.location.href);") { 

window.location.replace('https://example.com'); 
alert(" "); 
} 

}, true); 

Mes script vérifie si le JavaScript pour rediriger vers la mauvaise page est là, alors me envoie hors de l'URL de connexion correcte.

Ce script fonctionne correctement - si le alert() est présent. Supprimez le alert() et la page redirige vers la page de connexion brisée. Cependant, quand alert()est là, je ne vois jamais la boîte d'alerte, mais sont redirigés vers la bonne page.

Je pourrais laisser le alert() dedans, comme il ne semble jamais fonctionner, mais je voudrais l'enlever et avoir toujours la page rediriger vers la page désirée.

Mes questions à ce sujet:

  • Pourquoi est-ce se produire? Un problème de synchronisation est-il en cause?
  • Comment puis-je faire fonctionner correctement sans un appel alert() inutile?

Répondre

2

Ce code a quelques "conditions de concurrence". Avec le alert() manquant, l'ancien JS se déclenche toujours avant la fin du location.replace();.
L'alerte prend du temps. Avec lui en place, le location.replace finit avant qu'il ne peut.

La bonne chose à faire est d'arrêter le script et de déclencher le remplacement. Faites-le avec stopPropagation et preventDefault. Quelque chose comme:

window.addEventListener ('beforescriptexecute', function (e) { 
    if (document.getElementsByTagName ("script")[0].text.trim() 
     === "window.location.href = '/access/login?return_to=' + encodeURIComponent(window.location.href);" 
    ) { 
     e.stopPropagation(); 
     e.preventDefault(); 
     window.location.replace ('https://example.com'); 
    } 
}, true); 
+1

Ah !! Ceci explique cela; essayé et ça marche à merveille. Je ne connaissais pas auparavant stopPropagation, ni preventDefault. Merci pour votre temps! –

+0

De rien; heureux de vous aider. –