J'utilise $.post()
pour appeler un servlet en utilisant Ajax, puis en utilisant le fragment HTML résultant pour remplacer un div
élément dans la page actuelle de l'utilisateur. Cependant, si la session expire, le serveur envoie une directive de redirection pour envoyer l'utilisateur à la page de connexion. Dans ce cas, jQuery remplace l' div
élément par le contenu de la page de connexion, forçant les yeux de l'utilisateur à assister à une scène rare.
Comment puis-je gérer une directive de redirection à partir d'un appel Ajax avec jQuery 1.2.6?
javascript
jquery
ajax
redirect
Elliot Vargas
la source
la source
HttpContext.Response.AddHeader
contrôle et la réussite à ajaxsetup sont la voie à suivreRéponses:
J'ai lu cette question et mis en œuvre l'approche qui a été énoncée concernant la définition du code d'état HTTP de réponse à 278 afin d'éviter que le navigateur ne gère les redirections de manière transparente. Même si cela a fonctionné, j'étais un peu insatisfait car c'est un peu un hack.
Après avoir creusé davantage, j'ai abandonné cette approche et utilisé JSON . Dans ce cas, toutes les réponses aux demandes AJAX ont le code d'état 200 et le corps de la réponse contient un objet JSON qui est construit sur le serveur. Le JavaScript sur le client peut ensuite utiliser l'objet JSON pour décider de ce qu'il doit faire.
J'ai eu un problème similaire au vôtre. J'exécute une demande AJAX qui a 2 réponses possibles: une qui redirige le navigateur vers une nouvelle page et une qui remplace un formulaire HTML existant sur la page actuelle par un nouveau. Le code jQuery pour ce faire ressemble à ceci:
L'objet JSON "données" est construit sur le serveur pour avoir 2 membres:
data.redirect
etdata.form
. J'ai trouvé que cette approche était bien meilleure.la source
J'ai résolu ce problème en:
Ajout d'un en-tête personnalisé à la réponse:
Lier une fonction JavaScript à l'
ajaxSuccess
événement et vérifier si l'en-tête existe:la source
Aucun navigateur ne gère correctement les réponses 301 et 302. Et en fait, la norme dit même qu'ils devraient les gérer "de manière transparente", ce qui est un casse-tête MASSIVE pour les fournisseurs de la bibliothèque Ajax. Dans Ra-Ajax, nous avons été contraints d'utiliser le code d'état de réponse HTTP 278 (juste un code de réussite "inutilisé") pour gérer les redirections transparentes depuis le serveur ...
Cela m'énerve vraiment, et si quelqu'un ici a du "pull" dans le W3C, j'apprécierais que vous puissiez faire savoir au W3C que nous devons vraiment gérer nous-mêmes les codes 301 et 302 ...! ;)
la source
La solution qui a finalement été implémentée était d'utiliser un wrapper pour la fonction de rappel de l'appel Ajax et dans ce wrapper de vérifier l'existence d'un élément spécifique sur le morceau HTML renvoyé. Si l'élément a été trouvé, le wrapper a exécuté une redirection. Sinon, l'encapsuleur a transféré l'appel à la fonction de rappel réelle.
Par exemple, notre fonction wrapper était quelque chose comme:
Ensuite, lors de l'appel Ajax, nous avons utilisé quelque chose comme:
Cela a fonctionné pour nous car tous les appels Ajax renvoyaient toujours du HTML dans un élément DIV que nous utilisons pour remplacer une partie de la page. De plus, nous avions seulement besoin de rediriger vers la page de connexion.
la source
J'aime la méthode de Timmerz avec une légère touche de citron. Si vous obtenez un contentType de texte / html retourné lorsque vous attendez JSON , vous êtes très probablement redirigé. Dans mon cas, je recharge simplement la page et elle est redirigée vers la page de connexion. Oh, et vérifiez que l'état jqXHR est 200, ce qui semble idiot, car vous êtes dans la fonction d'erreur, non? Sinon, les cas d'erreur légitimes forceront un rechargement itératif (oups)
la source
Utilisez l'
$.ajax()
appel de bas niveau :Essayez ceci pour une redirection:
la source
Je voulais juste partager mon approche car cela pourrait aider quelqu'un:
J'ai essentiellement inclus un module JavaScript qui gère les éléments d'authentification comme l'affichage du nom d'utilisateur et également ce cas, la gestion de la redirection vers la page de connexion .
Mon scénario: Nous avons essentiellement un serveur ISA entre les deux qui écoute toutes les demandes et répond avec un 302 et un en-tête d'emplacement à notre page de connexion.
Dans mon module JavaScript, mon approche initiale était quelque chose comme
Le problème (comme beaucoup ici déjà mentionné) est que le navigateur gère lui-même la redirection, c'est pourquoi mon
ajaxComplete
rappel n'a jamais été appelé, mais à la place, j'ai obtenu la réponse de la page de connexion déjà redirigée qui était évidemment unstatus 200
. Le problème: comment détecter si la réponse 200 réussie est votre page de connexion réelle ou simplement une autre page arbitraire ??La solution
Comme je n'ai pas pu capturer 302 réponses de redirection, j'ai ajouté un en-
LoginPage
tête sur ma page de connexion qui contenait l'url de la page de connexion elle-même. Dans le module, j'écoute maintenant l'en-tête et fais une redirection:... et ça marche comme du charme :). Vous vous demandez peut-être pourquoi j'inclus l'URL dans l'en-
LoginPage
tête ... enfin, fondamentalement parce que je n'ai trouvé aucun moyen de déterminer l'URLGET
résultant de la redirection automatique de l'emplacement depuis l'xhr
objet ...la source
X-
, donc un meilleur en-tête à utiliser seraitX-LoginPage: http://example.com/login
.X-
.Je sais que ce sujet est ancien, mais je donnerai une autre approche que j'ai trouvée et décrite précédemment ici . Fondamentalement, j'utilise ASP.MVC avec WIF (mais ce n'est pas vraiment important pour le contexte de ce sujet - la réponse est adéquate quel que soit le cadre utilisé. L'indice reste inchangé - traitant des problèmes liés aux échecs d'authentification lors de l'exécution de requêtes ajax ) .
L'approche illustrée ci-dessous peut être appliquée à toutes les demandes ajax prédéfinies (si elles ne sont pas redéfinies avant l'événement Send évidemment).
Avant toute requête ajax, la
CheckPulse
méthode est invoquée (la méthode du contrôleur qui peut être la plus simple):Si l'utilisateur n'est pas authentifié (le jeton a expiré), cette méthode n'est pas accessible (protégée par un
Authorize
attribut). Étant donné que le framework gère l'authentification, tandis que le jeton expire, il place l'état http 302 dans la réponse. Si vous ne voulez pas que votre navigateur gère la réponse 302 de manière transparente, interceptez-la dans Global.asax et modifiez l'état de la réponse, par exemple 200 OK. De plus, ajoutez un en-tête, qui vous demande de traiter une telle réponse de manière spéciale (plus tard du côté client):Enfin, côté client, vérifiez cet en-tête personnalisé. Si présent - une redirection complète vers la page de connexion doit être effectuée (dans mon cas,
window.location
est remplacée par l'URL de la demande qui est gérée automatiquement par mon framework).la source
Je pense qu'une meilleure façon de gérer cela est de tirer parti des codes de réponse du protocole HTTP existants, en particulier
401 Unauthorized
.Voici comment je l'ai résolu:
Côté client: se lier aux événements ajax
OMI, c'est plus générique et vous n'écrivez pas de nouvelles spécifications / en-têtes personnalisés. Vous ne devriez pas non plus avoir à modifier aucun de vos appels ajax existants.
Edit: Selon le commentaire de @ Rob ci-dessous, 401 (le code d'état HTTP pour les erreurs d'authentification) devrait être l'indicateur. Voir 403 Interdit vs 401 Réponses HTTP non autorisées pour plus de détails. Cela étant dit, certains cadres Web utilisent 403 pour les erreurs d'authentification ET d'autorisation - alors adaptez-vous en conséquence. Merci Rob.
la source
J'ai résolu ce problème comme ceci:
Ajoutez un middleware pour traiter la réponse, s'il s'agit d'une redirection pour une demande ajax, modifiez la réponse en une réponse normale avec l'URL de redirection.
Ensuite, dans ajaxComplete, si la réponse contient une redirection, il doit s'agir d'une redirection, alors changez l'emplacement du navigateur.
la source
J'ai une solution simple qui fonctionne pour moi, aucun changement de code de serveur nécessaire ... il suffit d'ajouter une cuillère à café de muscade ...
Je vérifie la présence de la balise html, mais vous pouvez modifier l'indexOf pour rechercher la chaîne unique qui existe dans votre page de connexion ...
la source
Une autre solution que j'ai trouvée (particulièrement utile si vous souhaitez définir un comportement global) consiste à utiliser la
$.ajaxsetup()
méthode avec lastatusCode
propriété . Comme d'autres l'ont souligné, n'utilisez pas de code d'état de redirection (3xx
), utilisez plutôt un4xx
code d'état et gérez la redirection côté client.Remplacez
400
par le code d'état que vous souhaitez gérer. Comme déjà mentionné, cela401 Unauthorized
pourrait être une bonne idée. J'utilise le400
car il est très peu spécifique et je peux l'utiliser401
pour des cas plus spécifiques (comme des informations de connexion erronées). Ainsi, au lieu de rediriger directement, votre backend devrait renvoyer un4xx
code d'erreur lorsque la session a expiré et que vous gérez la redirection côté client. Fonctionne parfaitement pour moi même avec des frameworks comme backbone.jsla source
La plupart des solutions données utilisent une solution de contournement, en utilisant un en-tête supplémentaire ou un code HTTP inapproprié. Ces solutions fonctionneront très probablement mais se sentiront un peu «hacky». J'ai trouvé une autre solution.
Nous utilisons WIF qui est configuré pour rediriger (passiveRedirectEnabled = "true") sur une réponse 401. La redirection est utile lors du traitement des requêtes normales mais ne fonctionnera pas pour les requêtes AJAX (puisque les navigateurs n'exécuteront pas la redirection 302 /).
En utilisant le code suivant dans votre global.asax, vous pouvez désactiver la redirection pour les demandes AJAX:
Cela vous permet de renvoyer 401 réponses pour les demandes AJAX, que votre javascript peut ensuite gérer en rechargeant la page. Le rechargement de la page lancera un 401 qui sera géré par WIF (et WIF redirigera l'utilisateur vers la page de connexion).
Un exemple de javascript pour gérer les erreurs 401:
la source
Ce problème peut apparaître lors de l'utilisation de la méthode ASP.NET MVC RedirectToAction. Pour empêcher le formulaire d'afficher la réponse en div, vous pouvez simplement faire une sorte de filtre de réponse ajax pour les réponses entrantes avec $ .ajaxSetup . Si la réponse contient une redirection MVC, vous pouvez évaluer cette expression du côté JS. Exemple de code pour JS ci-dessous:
Si les données sont: "window.location = '/ Acount / Login'" ci-dessus, le filtre interceptera et évaluera pour effectuer la redirection au lieu de laisser les données à afficher.
la source
data
se trouve dans le corps ou l'en-tête de la réponse?Réunissant ce que Vladimir Prudnikov et Thomas Hansen ont dit:
Cela fait que le navigateur traite la réponse comme un succès et la transmet à votre Javascript.
la source
la source
Essayer
Mettez-le sur la page de connexion. S'il a été chargé dans un div sur la page principale, il sera redirigé jusqu'à la page de connexion. "#site" est un identifiant de div qui se trouve sur toutes les pages sauf la page de connexion.
la source
Bien que les réponses semblent fonctionner pour les gens si vous utilisez Spring Security, j'ai trouvé l'extension de LoginUrlAuthenticationEntryPoint et l'ajout de code spécifique pour gérer AJAX plus robuste. La plupart des exemples interceptent toutes les redirections, pas seulement les échecs d'authentification. Ce n'était pas souhaitable pour le projet sur lequel je travaille. Vous devrez peut-être également étendre ExceptionTranslationFilter et remplacer la méthode "sendStartAuthentication" pour supprimer l'étape de mise en cache si vous ne voulez pas que la demande AJAX en échec soit mise en cache.
Exemple AjaxAwareAuthenticationEntryPoint:
Sources: 1 , 2
la source
J'ai résolu cela en mettant ce qui suit dans ma page login.php.
la source
Permettez-moi de citer à nouveau le problème décrit par @Steg
À mon humble avis, il s'agit d'un véritable défi et devra être officiellement étendu aux normes HTTP actuelles.
Je crois que la nouvelle norme Http sera d'utiliser un nouveau code d'état. Signification:
301/302
indique actuellement au navigateur d'aller chercher le contenu de cette demande dans une nouvellelocation
.Dans le standard étendu, il dira que si la réponse
status: 308
(juste un exemple), alors le navigateur devrait rediriger la page principale vers lalocation
fournie.Cela étant dit; Je suis enclin à imiter déjà ce comportement futur , et donc quand un document.redirect est nécessaire, je demande au serveur de répondre comme:
Lorsque JS obtient le "
status: 204
", il vérifie l'existence de l'en-x-status: 308
tête et fait un document.redirect à la page fournie dans l'en-location
tête.Est-ce que cela a un sens pour vous?
la source
Certains pourraient trouver les informations ci-dessous utiles:
Je voulais que les clients soient redirigés vers la page de connexion pour toute action de repos envoyée sans jeton d'autorisation. Étant donné que toutes mes actions de repos sont basées sur Ajax, j'avais besoin d'un bon moyen générique pour rediriger vers la page de connexion au lieu de gérer la fonction de réussite Ajax.
Voici ce que j'ai fait:
Sur toute demande Ajax, mon serveur retournera une réponse Json 200 "BESOIN D'AUTHENTIFIER" (si le client a besoin de s'authentifier).
Exemple simple en Java (côté serveur):
Dans mon Javascript, j'ai ajouté le code suivant:
Et c'est tout.
la source
dans le servlet, vous devez mettre
response.setStatus(response.SC_MOVED_PERMANENTLY);
pour envoyer le statut xmlHttp '301' dont vous avez besoin pour une redirection ...et dans la fonction $ .ajax vous ne devez pas utiliser la
.toString()
fonction ..., justeif (xmlHttp.status == 301) { top.location.href = 'xxxx.jsp'; }
le problème est qu'il n'est pas très flexible, vous ne pouvez pas décider où vous souhaitez rediriger ..
la redirection via les servlets devrait être le meilleur moyen. mais je ne trouve toujours pas la bonne façon de le faire.
la source
Je voulais juste m'accrocher à toutes les demandes ajax pour la page entière. @SuperG m'a fait démarrer. Voici ce que j'ai fini avec:
Je voulais vérifier spécifiquement certains codes de statut http sur lesquels baser ma décision. Cependant, vous pouvez simplement vous lier à ajaxError pour obtenir autre chose que du succès (200 seulement peut-être?) J'aurais pu écrire:
la source
Si vous souhaitez également transmettre les valeurs, vous pouvez également définir les variables de session et accéder par exemple: dans votre jsp, vous pouvez écrire
Et puis vous pouvez stocker cette valeur temporaire dans votre variable javascript et jouer
la source
Je n'ai eu aucun succès avec la solution d'en-tête - ils n'ont jamais été récupérés dans ma méthode ajaxSuccess / ajaxComplete. J'ai utilisé la réponse de Steg avec la réponse personnalisée, mais j'ai modifié certains côté JS. J'ai configuré une méthode que j'appelle dans chaque fonction afin que je puisse utiliser les méthodes
$.get
et standards$.post
.Exemple d'utilisation ...
la source
Enfin, je résous le problème en ajoutant une coutume
HTTP Header
. Juste avant la réponse pour chaque demande côté serveur, j'ajoute l'URL actuellement demandée à l'en-tête de la réponse.Mon type d'application sur le serveur est
Asp.Net MVC
, et il a un bon endroit pour le faire. enGlobal.asax
j'ai implémenté l'Application_EndRequest
événement donc:Cela fonctionne parfaitement pour moi! Maintenant , dans chaque réponse du
JQuery
$.post
j'ai demandé les en-url
têtes de réponse et aussi d' autres qui vient à la suite de laPOST
méthode par le statut302
,303
....et une autre chose importante est qu'il n'est pas nécessaire de modifier le code côté serveur ou côté client.
et le suivant est la possibilité d'accéder aux autres informations de post-action telles que les erreurs, les messages et ..., de cette façon.
J'ai posté ça, peut-être aider quelqu'un :)
la source
J'avais ce problème sur une application django avec laquelle je bricolais (avertissement: je bricole pour apprendre, et je ne suis en aucun cas un expert). Ce que je voulais faire, c'était utiliser jQuery ajax pour envoyer une demande DELETE à une ressource, la supprimer côté serveur, puis renvoyer une redirection vers (essentiellement) la page d'accueil. Quand j'ai envoyé à
HttpResponseRedirect('/the-redirect/')
partir du script python, la méthode ajax de jQuery recevait 200 au lieu de 302. Donc, ce que j'ai fait était d'envoyer une réponse de 300 avec:Ensuite, j'ai envoyé / traité la demande sur le client avec jQuery.ajax comme ceci:
Peut-être que l'utilisation de 300 n'est pas "correcte", mais au moins cela a fonctionné comme je le voulais.
PS: ce fut une énorme douleur à éditer sur la version mobile de SO. Stupide FAI a traité ma demande d'annulation de service juste après avoir fini avec ma réponse!
la source
Vous pouvez également accrocher le prototype d'envoi XMLHttpRequest. Cela fonctionnera pour tous les envois (jQuery / dojo / etc) avec un gestionnaire.
J'ai écrit ce code pour gérer une erreur expirée de 500 pages, mais cela devrait aussi bien fonctionner pour intercepter une redirection 200. Préparez l'entrée wikipedia sur XMLHttpRequest onreadystatechange sur la signification de readyState.
la source
De plus, vous souhaiterez probablement rediriger l'utilisateur vers l'URL indiquée dans les en-têtes. Donc, finalement, cela ressemblera à ceci:
UPD: Opps. Ont la même tâche, mais cela ne fonctionne pas. Faire ce genre de choses. Je vous montrerai une solution quand je la trouverai.
la source
Je suis un solulion de travail en utilisant les réponses de @John et @Arpad lien et @RobWinch lien
J'utilise Spring Security 3.2.9 et jQuery 1.10.2.
Étendez la classe de Spring pour provoquer une réponse 4XX uniquement à partir des requêtes AJAX:
applicationContext-security.xml
Dans mes JSP, ajoutez un gestionnaire d'erreur AJAX global comme indiqué ici
Supprimez également les gestionnaires d'erreurs existants des appels AJAX dans les pages JSP:
J'espère que cela aide les autres.
Update1 J'ai trouvé que je devais ajouter l'option (always-use-default-target = "true") à la configuration de connexion au formulaire. Cela était nécessaire car après qu'une demande AJAX a été redirigée vers la page de connexion (en raison de la session expirée), Spring se souvient de la demande AJAX précédente et y redirige automatiquement après la connexion. Cela provoque l'affichage du JSON renvoyé sur la page du navigateur. Bien sûr, pas ce que je veux.
Update2 Au lieu d'utiliser
always-use-default-target="true"
, utilisez l'exemple @RobWinch de blocage des requêtes AJAX à partir du requstCache. Cela permet aux liens normaux d'être redirigés vers leur cible d'origine après la connexion, mais AJAX accède à la page d'accueil après la connexion.la source