2009-08-20 8 views
1

Je travaille sur un projet qui utilise l'authentification de l'utilisateur. Je suis confronté à un problème avec mes requêtes AJAX si aucune session authentifiée n'est présente lors de la demande.Ajax - Je dois vérifier si une session valide existe avant chaque requête AJAX

J'ai un délai d'attente de session de 3min, donc si l'utilisateur reste inactif pendant 3 minutes puis effectue une action qui provoque une requête AJAX, la requête échoue et renvoie une erreur 403. Voici ce que j'ai l'intention de faire est d'intercepter toute la requête AJAX de la page et envoyé un ping au serveur qui retournera un objet JSON indiquant s'il existe une session valide. S'il y en a un, le client continuera avec la requête en cours, sinon il rechargera la page en cours, ce qui amènera l'utilisateur à la page de connexion et l'utilisateur devra à nouveau fournir les informations d'identification.

Voici ma mise en œuvre.

$("#param-ajax").ajaxSend(function(evt, request, settings) { 
var pingurl = GtsJQuery.getContextPath() + '/ping.json'; 
var escapedurl = pingurl.replace(/\//g, "\\/"); 

var regexpr1 = eval('/^' + escapedurl + '\\?.*$/'); 
var regexpr2 = eval('/^' + escapedurl + '$/'); 
// Proceed with the ping only if the url is not the ping url else it will 
// cause recursive calls which will never end. 
if (!regexpr1.test(settings.url) && !regexpr2.test(settings.url)) { 
    var timeout = false; 
    $.ajax({ 
       url : pingurl, 
       cache : false, 
       data : { 
        url : settings.url 
       }, 
       async : false, 
       complete : function(request, status) { 
        if (status == "error") { 
         try { 
          // GtsJQuery.getJsonObject() converts the string 
          // response to a JSON object 
          var result = GtsJQuery 
            .getJsonObject(request.responseText) 
          if (result.timeout) { 
           timeout = true; 
           return; 
          } 
         } catch (e) { 
          // ignore the error. This should never occure. 
         } 
        } 
       } 
      }); 
    // Reload the window if there is a timeout -- means there is no valid 
    // sesstion 
    if (timeout) { 
     window.location.reload(); 
    } 
} 
}); 

Ici, tout beau travail comprenait la window.location.reload(), mais la demande ajax original n'est pas avorté. Comme la requête AJAX d'origine n'est pas abandonnée après le déclenchement du rechargement de la page, la requête AJAX est également envoyée au serveur. Je veux un mécanisme qui me permettra d'annuler la demande d'origine si le délai d'attente s'avère être vrai.

This post offre une réponse, mais le problème reste avec les plugins tiers comme les datatables qui utilise AJAX. Nous ne pouvons pas écrire de gestionnaire d'erreurs pour ces requêtes AJAX.

Merci.

Répondre

0

j'ai changé mon concept maintenant, je vérifier le XMLHttpRequest dans le côté serveur en utilisant l'en-tête de demande 'x demandée avec.

S'il s'agit d'une requête xmlHTTPRequest alors 'x-requested-with' aura la valeur 'XMLHttpRequest'. Les bibliothèques javascript (EXTjs et jQuery) que j'utilise définissent cet en-tête correctement.

Voici mon code côté serveur

boolean isAjaxRequest = StringUtils.endsWithIgnoreCase(request.getHeader("x-requested-with"), "XMLHttpRequest") 

EDIT

Si la demande donnée est une demande de paiement ajax sera la réponse des données JSON qui aura le statut 403 et contiendra une clé appelée délai d'attente avec valeur true ex: {timeout: true, ....}

Ensuite, nous allons gérer cela dans le gestionnaire d'événements $ .ajaxError() traitera l'erreur. Si le statut de l'erreur est 403 et que la valeur du délai d'attente est true, je rechargerai la page.

+2

Je pense encore que vous n'avez pas abordé la façon dont vous gérez la partie rechargement du problème. L'utilisation de l'en-tête 'x-requested-with' est un bon moyen de savoir si la requête donnée est une requête AJAX –

2

Si je comprends bien la situation, vous n'avez pas besoin de cela. Dans votre requête AJAX d'origine, ajoutez simplement une fonction d'erreur qui redirigera l'utilisateur.

errHandler = function(XMLHttpRequest, textStatus, errorThrown) { 
     if(textStatus.match(/forbidden/i)) { 
     redirectUserToLoginHere(); 
     } 
} 

$.ajax({ 

    success: yourFunctionHere, 

    error: errHandler 
}) 

alors vous pourriez être en mesure de faire une enveloppe ajax qui a toujours ErrHandler de sorte que vous ne pas le placer dans chaque appel ajax.

EDIT:

après une expérimentation, si un gestionnaire « ajaxSend » jette une erreur, ne sera jamais envoyé la demande initiale.

En outre, si le gestionnaire fait

document.location = '/login'; 

alors la demande initiale est jamais envoyé.

Espérons que cela aide :)

+0

Le problème est que j'utilise des outils tiers tels que les datatables qui utilisent AJAX en interne pour récupérer des données. Je ne peux pas écrire un gestionnaire d'erreur là-bas, encore une fois je ne veux pas que toutes les demandes traitent ce cas séparément. –

Questions connexes