2010-06-21 5 views
3

J'utilise asp.net mvc, C# et jquery. Mon site utilise largement ajax. Cela a conduit à un problème et je ne suis pas sûr de savoir comment le réparer (bien le réparer mieux que ma solution actuelle).Comment surmonteriez-vous ce problème? Jquery + ajax + serveur timeout

Scénario.

  1. Identifiants dans mon site - l'ensemble de cookies, le serveur a délai de 30 minutes
  2. utilisateur se éloigne pendant 30 minutes
  3. utilisateur revient et clique sur un mon ajax permis onglets jquery
  4. demande écrite adressée à serveur
  5. Le serveur ne redémarre pas l'utilisateur et renvoie-le à la page de connexion.
  6. étant donné qu'il s'agit d'une requête ajax, la redirection est restituée dans l'onglet. Il semble moche (une page entière rendue dans un onglet), l'utilisateur est probablement extrêmement confus à ce stade.

Problème

  1. En ce qui concerne le serveur et ajax est concerné la demande ajax est valide et la réponse de succès est renvoyé. Donc, je ne peux pas aller vérifier une erreur car la demande a réussi, mais pas les bonnes données qui reviennent.

Solution 1

  1. connexions utilisateur dans le site.
  2. Jquery demande ajax fait pour savoir les utilisateurs de délai d'attente
  3. délai
  4. est de 60 secondes à moins de délai d'attente du serveur
  5. Une fois temporisation javascript côté est touché. La boîte de dialogue Jquery arrive et leur indique que leur session a expiré et les force à être redirigés pour se connecter.
    • Un utilisateur ne peut pas cliquer sur quoi que ce soit car la boîte de dialogue bloque cela. Si certains utilisateurs firebug ou quelque chose ils peuvent le supprimer, mais le délai d'expiration du serveur sera toujours effet et ils obtiendront la version laide (ne vous inquiétez pas alors).
  6. Si un utilisateur effectue une requête ajax, le délai du côté serveur est réinitialisé ainsi que celui du côté client.

Problèmes

  1. L'utilisateur peut à pied et une autre personne pourrait venir le message de délai d'attente pourrait être en place, mais ils ont quand même pu avoir un potentiel de 45 secondes d'essayer de faire une nouvelle demande et réinitialiser le temps libre. C'est très bas et pas trop inquiet à ce sujet.

  2. Parfois, j'ai observé qu'il est juste temps (le côté client) et je ne sais pas pourquoi. Je ne peux jamais recréer le problème (semble arriver à d'autres personnes mais pas quand je suis en train de tester). Donc je devine que quelque chose n'a pas frappé écrire ou quelque chose d'autre a mal tourné.

Donc le numéro 2 est vraiment la grande raison pour laquelle je voudrais trouver une autre solution.

Solution 2 (spéculation). Je pensais peut-être que si je peux faire mon propre entête de réponse ou quelque chose comme ça, si le serveur arrive à expiration, je peux envoyer une redirection 303 ou quelque chose de cette nature que je pourrais vérifier puis faire une redirection jquery.

Cependant, je ne sais pas où faire cela dans mon code C# ou si je peux faire quelque chose comme ça.

+0

Je l'écris comme un commentaire, parce que ma solution est si simple que j'ai le sentiment que je n'ai pas compris la question. lorsque vous envoyez une réponse à partir du serveur inclure des informations (en json) est la session a expiré ou non. la partie client va le vérifier avant de mettre à div. if expired => rediriger vers la page de connexion – Andrey

+0

Eh bien, le problème est qu'il n'atteint jamais la partie où mon json est envoyé. Comme si le délai d'attente du serveur, il ne continue pas et fait la méthode d'action, puis le bloque. Il le bloque avant qu'il ne passe dans la méthode. Donc je ne peux rien mettre là-bas. – chobo2

Répondre

3

Vous pouvez toujours ajouter un en-tête HTTP personnalisé dans votre action LogOn qui pourrait être intercepté par des appels AJAX et d'agir en conséquence:

public ActionResult LogOn() 
{ 
    Response.AddHeader("X-LOGON", "LogOn"); 
    return View(); 
} 

Et dans le chèque de rappel de succès pour la présence de cet en-tête:

$.ajax({ 
    url: '/home/someaction', 
    success: function (data, textStatus, XMLHttpRequest) { 
     if (XMLHttpRequest.getResponseHeader('X-LOGON') === 'LogOn') { 
      // the LogOn page is being displayed 
      // probably timeout or unaithorized => act accordingly 
     } 
    } 
}); 
+1

Peut-être mieux dans un gestionnaire ajax global - de cette façon, vous n'avez pas à vérifier partout. La chose que je n'aime pas à ce sujet est que l'utilisateur peut passer beaucoup de temps à faire quelque chose seulement pour l'effacer parce qu'il est soumis après l'expiration de la session. Je préfère les prévenir avant cet événement et les laisser prendre des mesures pour l'éviter. – tvanfosson

+0

@tvanfosson, oui, bonne idée, '$ .ajaxSetup' semble être un bon endroit pour le faire une fois pour toutes. –

+0

@tvanfosson, donc vous interrogez périodiquement le serveur pour détecter que le ticket d'authentification est toujours valide? –

2

Je ne vois pas pourquoi votre gestionnaire d'authentification (filtre d'action) ne peut pas gérer cela en retournant 403 (interdit) que le gestionnaire AJAX va ensuite traiter en définissant window.location à/login.

+0

C'est exactement ce que fait le gestionnaire d'authentification, le problème est qu'il est intercepté par le moteur ASP.NET et redirigé vers la page de connexion => tout ce que jQuery voit est un code d'état 200 sur la page de connexion. –

+0

Alors, Darin, tu connais les alentours? Puis-je le garder avec 403 ou 303 ou quelque chose de non 200? – chobo2

+0

C'est pourquoi j'ai dit "votre gestionnaire d'authentification/filtre". Créez votre propre AuthorizeAttribute et remplacez OnAuthorization pour retourner ForbiddenResult. C'est ASP.NET MVC, vous pouvez faire ce que vous voulez. J'utilise en fait la technique que je décris. – queen3

2

Je fais essentiellement la solution 1, sauf que (1) je l'ai encapsulé dans un plugin et (2) j'injecte le délai d'attente de session dans la page quand il rend. Vous pouvez voir les détails sur mon blog, http://farm-fresh-code.blogspot.com, dans ce article. Un ajout est que, lorsque le côté client expire, il appelle automatiquement l'action de déconnexion pour terminer la session.