Ich verwende $.post()
, um ein Servlet mit Ajax aufzurufen und dann das resultierende HTML-Fragment zu verwenden, um ein div
Element auf der aktuellen Seite des Benutzers zu ersetzen . Wenn die Sitzung jedoch abgelaufen ist, sendet der Server eine Umleitungsanweisung, um den Benutzer zur Anmeldeseite zu senden. In diesem Fall ersetzt jQuery das div
Element durch den Inhalt der Anmeldeseite und zwingt die Augen des Benutzers, tatsächlich eine seltene Szene zu sehen.
Wie kann ich eine Umleitungsanweisung von einem Ajax-Aufruf mit jQuery 1.2.6 verwalten?
javascript
jquery
ajax
redirect
Elliot Vargas
quelle
quelle
HttpContext.Response.AddHeader
und Check bei Ajaxsetup Erfolg ist der richtige WegAntworten:
Ich habe diese Frage gelesen und den Ansatz implementiert, der in Bezug auf das Setzen des Antwort- HTTP-Statuscodes auf 278 angegeben wurde, um zu vermeiden, dass der Browser die Weiterleitungen transparent behandelt. Obwohl dies funktionierte, war ich ein wenig unzufrieden, da es ein bisschen ein Hack ist.
Nachdem ich mich weiter umgesehen hatte, gab ich diesen Ansatz auf und verwendete JSON . In diesem Fall haben alle Antworten auf AJAX-Anforderungen den Statuscode 200 und der Hauptteil der Antwort enthält ein JSON-Objekt, das auf dem Server erstellt wird. Das JavaScript auf dem Client kann dann anhand des JSON-Objekts entscheiden, was zu tun ist.
Ich hatte ein ähnliches Problem wie Sie. Ich führe eine AJAX-Anfrage mit zwei möglichen Antworten aus: eine, die den Browser auf eine neue Seite umleitet, und eine, die ein vorhandenes HTML-Formular auf der aktuellen Seite durch ein neues ersetzt. Der dazu erforderliche jQuery-Code sieht ungefähr so aus:
Das JSON-Objekt "data" ist auf dem Server so aufgebaut, dass es zwei Mitglieder hat:
data.redirect
unddata.form
. Ich fand diesen Ansatz viel besser.quelle
Ich habe dieses Problem gelöst durch:
Hinzufügen eines benutzerdefinierten Headers zur Antwort:
Binden einer JavaScript-Funktion an das
ajaxSuccess
Ereignis und Überprüfen, ob der Header vorhanden ist:quelle
Kein Browser verarbeitet 301- und 302-Antworten korrekt. Tatsächlich sagt der Standard sogar, dass sie "transparent" damit umgehen sollten, was für Anbieter von Ajax Library ein MASSIVES Problem darstellt. In Ra-Ajax mussten wir den HTTP-Antwortstatuscode 278 (nur einen "nicht verwendeten" Erfolgscode) verwenden, um transparente Weiterleitungen vom Server zu verarbeiten ...
Das ärgert mich wirklich, und wenn jemand hier etwas "Pull" in W3C hat, würde ich es begrüßen, wenn Sie W3C wissen lassen könnten , dass wir wirklich 301- und 302-Codes selbst verarbeiten müssen ...! ;)
quelle
Die Lösung, die schließlich implementiert wurde, bestand darin, einen Wrapper für die Rückruffunktion des Ajax-Aufrufs zu verwenden und in diesem Wrapper zu prüfen, ob ein bestimmtes Element im zurückgegebenen HTML-Block vorhanden ist. Wenn das Element gefunden wurde, führte der Wrapper eine Umleitung aus. Wenn nicht, leitete der Wrapper den Anruf an die eigentliche Rückruffunktion weiter.
Zum Beispiel war unsere Wrapper-Funktion so etwas wie:
Beim Ajax-Anruf haben wir dann Folgendes verwendet:
Dies funktionierte für uns, da alle Ajax-Aufrufe immer HTML in einem DIV-Element zurückgaben, mit dem wir einen Teil der Seite ersetzen. Außerdem mussten wir nur zur Anmeldeseite umleiten.
quelle
Ich mag Timmerz 'Methode mit einem leichten Schuss Zitrone. Wenn Sie jemals ContentType von Text / HTML zurückerhalten, wenn Sie JSON erwarten , werden Sie höchstwahrscheinlich umgeleitet. In meinem Fall lade ich die Seite einfach neu und sie wird auf die Anmeldeseite umgeleitet. Oh, und überprüfen Sie, ob der jqXHR-Status 200 ist, was albern erscheint, weil Sie sich in der Fehlerfunktion befinden, oder? Andernfalls erzwingen legitime Fehlerfälle ein iteratives Neuladen (oops)
quelle
Verwenden Sie den Low-Level-
$.ajax()
Anruf:Versuchen Sie dies für eine Weiterleitung:
quelle
Ich wollte nur meinen Ansatz teilen, da dies jemandem helfen könnte:
Ich habe im Grunde ein JavaScript-Modul eingefügt, das die Authentifizierung wie die Anzeige des Benutzernamens und auch in diesem Fall die Weiterleitung zur Anmeldeseite behandelt .
Mein Szenario: Wir haben im Grunde einen ISA-Server dazwischen, der alle Anfragen abhört und mit einem 302 und einem Standort-Header auf unsere Anmeldeseite antwortet .
In meinem JavaScript-Modul war mein ursprünglicher Ansatz so etwas wie
Das Problem (wie viele hier bereits erwähnt haben) ist, dass der Browser die Umleitung selbst erledigt, weshalb mein
ajaxComplete
Rückruf nie aufgerufen wurde, sondern die Antwort der bereits umgeleiteten Anmeldeseite, die offensichtlich eine warstatus 200
. Das Problem: Wie erkennen Sie, ob die erfolgreiche 200-Antwort Ihre tatsächliche Anmeldeseite oder nur eine andere beliebige Seite ist?Die Lösung
Da ich 302 Weiterleitungsantworten nicht erfassen konnte, fügte ich
LoginPage
meiner Anmeldeseite einen Header hinzu, der die URL der Anmeldeseite selbst enthielt. Im Modul höre ich jetzt auf den Header und mache eine Umleitung:... und das funktioniert wie Charme :). Sie fragen sich vielleicht, warum ich die URL in den
LoginPage
Header aufgenommen habe ... im Grunde genommen, weil ich keine Möglichkeit gefunden habe, die URL zu bestimmen, dieGET
sich aus der automatischen Standortumleitung vomxhr
Objekt ergibt ...quelle
X-
, daher wäre ein besserer Header zu verwendenX-LoginPage: http://example.com/login
.X-
.Ich weiß, dass dieses Thema alt ist, aber ich werde noch einen anderen Ansatz nennen, den ich hier gefunden und zuvor beschrieben habe . Grundsätzlich verwende ich ASP.MVC mit WIF (dies ist jedoch für den Kontext dieses Themas nicht wirklich wichtig - die Antwort ist ausreichend, unabhängig davon, welche Frameworks verwendet werden. Der Hinweis bleibt unverändert - und behandelt Probleme im Zusammenhang mit Authentifizierungsfehlern beim Ausführen von Ajax-Anforderungen ) .
Der unten gezeigte Ansatz kann auf alle sofort einsatzbereiten Ajax-Anforderungen angewendet werden (wenn sie das Ereignis vor dem Senden offensichtlich nicht neu definieren).
Bevor eine Ajax-Anforderung ausgeführt wird, wird die
CheckPulse
Methode aufgerufen (die Controller-Methode, die am einfachsten sein kann):Wenn der Benutzer nicht authentifiziert ist (Token abgelaufen ist), kann auf diese Methode nicht zugegriffen werden (geschützt durch
Authorize
Attribut). Da das Framework die Authentifizierung verwaltet, während das Token abläuft, setzt es den http-Status 302 auf die Antwort. Wenn Sie nicht möchten, dass Ihr Browser die 302-Antwort transparent verarbeitet, fangen Sie sie in Global.asax ab und ändern Sie den Antwortstatus - beispielsweise auf 200 OK. Fügen Sie außerdem einen Header hinzu, der Sie anweist, eine solche Antwort auf besondere Weise zu verarbeiten (später auf der Clientseite):Überprüfen Sie schließlich auf der Clientseite, ob ein solcher benutzerdefinierter Header vorhanden ist. Wenn vorhanden, sollte eine vollständige Umleitung zur Anmeldeseite erfolgen (in meinem Fall
window.location
wird die URL von der Anfrage ersetzt, die von meinem Framework automatisch verarbeitet wird).quelle
Ich denke, ein besserer Weg, dies zu handhaben, besteht darin, die vorhandenen HTTP-Protokoll-Antwortcodes speziell zu nutzen
401 Unauthorized
.So habe ich es gelöst:
Client-Seite: Binden Sie an die Ajax-Ereignisse
IMO ist dies allgemeiner und Sie schreiben keine neuen benutzerdefinierten Spezifikationen / Header. Sie sollten auch keinen Ihrer vorhandenen Ajax-Aufrufe ändern müssen.
Bearbeiten: Gemäß dem Kommentar von @ Rob unten sollte 401 (der HTTP-Statuscode für Authentifizierungsfehler) der Indikator sein. Weitere Informationen finden Sie unter 403 Verbotene vs 401 Nicht autorisierte HTTP-Antworten . Vor diesem Hintergrund verwenden einige Web-Frameworks 403 sowohl für Authentifizierungs- als auch für Autorisierungsfehler. Passen Sie sie daher entsprechend an. Danke Rob.
quelle
Ich habe dieses Problem folgendermaßen gelöst:
Fügen Sie eine Middleware hinzu, um die Antwort zu verarbeiten. Wenn es sich um eine Umleitung für eine Ajax-Anforderung handelt, ändern Sie die Antwort in eine normale Antwort mit der Umleitungs-URL.
Wenn die Antwort in ajaxComplete eine Umleitung enthält, muss es sich um eine Umleitung handeln. Ändern Sie daher den Speicherort des Browsers.
quelle
Ich habe eine einfache Lösung, die für mich funktioniert, keine Änderung des Servercodes erforderlich ... fügen Sie einfach einen Teelöffel Muskatnuss hinzu ...
Ich überprüfe das Vorhandensein eines HTML-Tags, aber Sie können den indexOf ändern, um nach einer eindeutigen Zeichenfolge auf Ihrer Anmeldeseite zu suchen ...
quelle
Eine andere Lösung, die ich gefunden habe (besonders nützlich, wenn Sie ein globales Verhalten festlegen möchten), besteht darin, die
$.ajaxsetup()
Methode zusammen mit derstatusCode
Eigenschaft zu verwenden . Verwenden Sie, wie bereits erwähnt, keinen Redirect-Statuscode (3xx
), sondern einen4xx
Statuscode und behandeln Sie die Weiterleitung clientseitig.Ersetzen Sie
400
durch den Statuscode, den Sie verarbeiten möchten. Wie schon erwähnt401 Unauthorized
könnte eine gute Idee sein. Ich benutze das,400
da es sehr unspezifisch ist und ich das401
für spezifischere Fälle verwenden kann (wie falsche Anmeldeinformationen). Anstatt direkt umzuleiten, sollte Ihr Backend einen4xx
Fehlercode zurückgeben, wenn die Sitzung abgelaufen ist und Sie die Umleitung clientseitig durchführen. Funktioniert perfekt für mich, auch mit Frameworks wie backbone.jsquelle
Die meisten der angegebenen Lösungen verwenden eine Problemumgehung, indem sie einen zusätzlichen Header oder einen ungeeigneten HTTP-Code verwenden. Diese Lösungen werden höchstwahrscheinlich funktionieren, fühlen sich aber ein bisschen "hacky" an. Ich habe eine andere Lösung gefunden.
Wir verwenden WIF, das für die Umleitung (passiveRedirectEnabled = "true") für eine 401-Antwort konfiguriert ist. Die Umleitung ist nützlich, wenn normale Anforderungen verarbeitet werden, funktioniert jedoch nicht für AJAX-Anforderungen (da Browser die 302 / -Umleitung nicht ausführen).
Mit dem folgenden Code in Ihrer Datei global.asax können Sie die Umleitung für AJAX-Anforderungen deaktivieren:
Auf diese Weise können Sie 401 Antworten für AJAX-Anforderungen zurückgeben, die Ihr Javascript dann durch erneutes Laden der Seite verarbeiten kann. Beim erneuten Laden der Seite wird ein 401 ausgegeben, der von WIF verarbeitet wird (und WIF leitet den Benutzer zur Anmeldeseite weiter).
Ein Beispiel für Javascript zur Behandlung von 401-Fehlern:
quelle
Dieses Problem kann dann bei Verwendung der ASP.NET MVC RedirectToAction-Methode auftreten. Um zu verhindern, dass das Formular die Antwort in div anzeigt, können Sie einfach eine Art Ajax-Antwortfilter für eingehende Antworten mit $ .ajaxSetup ausführen . Wenn die Antwort eine MVC-Umleitung enthält, können Sie diesen Ausdruck auf der JS-Seite auswerten. Beispielcode für JS unten:
Wenn die Daten lauten : "window.location = '/ Acount / Login'" über dem Filter, wird dies abgefangen und ausgewertet, um die Umleitung vorzunehmen, anstatt die Daten anzeigen zu lassen.
quelle
data
befindet sich im Antworttext oder in der Kopfzeile?Zusammenstellen, was Vladimir Prudnikov und Thomas Hansen gesagt haben:
Dadurch behandelt der Browser die Antwort als Erfolg und gibt sie an Ihr Javascript weiter.
quelle
quelle
Versuchen
Stellen Sie es auf die Anmeldeseite. Wenn es in ein div auf der Hauptseite geladen wurde, wird es auf die Anmeldeseite umgeleitet. "#site" ist eine ID eines div, die sich auf allen Seiten außer der Anmeldeseite befindet.
quelle
Während die Antworten für Benutzer zu funktionieren scheinen, wenn Sie Spring Security verwenden, habe ich festgestellt, dass LoginUrlAuthenticationEntryPoint erweitert und spezifischer Code hinzugefügt wird, um AJAX robuster zu handhaben. Die meisten Beispiele fangen alle Weiterleitungen ab, nicht nur Authentifizierungsfehler. Dies war für das Projekt, an dem ich arbeite, unerwünscht. Möglicherweise müssen Sie auch ExceptionTranslationFilter erweitern und die Methode "sendStartAuthentication" überschreiben, um den Caching-Schritt zu entfernen, wenn die fehlgeschlagene AJAX-Anforderung nicht zwischengespeichert werden soll.
Beispiel AjaxAwareAuthenticationEntryPoint:
Quellen: 1 , 2
quelle
Ich habe dieses Problem gelöst, indem ich Folgendes in meine login.php-Seite eingefügt habe.
quelle
Lassen Sie mich noch einmal das von @Steg beschriebene Problem zitieren
IMHO ist dies eine echte Herausforderung und muss offiziell auf die aktuellen HTTP-Standards erweitert werden.
Ich glaube, der neue HTTP-Standard wird darin bestehen, einen neuen Statuscode zu verwenden. Bedeutung:
301/302
Weist den Browser derzeit an, den Inhalt dieser Anforderung in eine neue zu holenlocation
.Im erweiterten Standard heißt es, dass
status: 308
der Browser bei einer Antwort (nur ein Beispiel) die Hauptseite auf dielocation
bereitgestellte Seite umleiten sollte .Davon abgesehen; Ich bin geneigt, dieses zukünftige Verhalten bereits nachzuahmen. Wenn daher eine document.redirect benötigt wird, muss der Server wie folgt antworten:
Wenn JS das "
status: 204
" erhält , prüft es, ob derx-status: 308
Header vorhanden ist, und führt eine document.redirect zu der imlocation
Header angegebenen Seite durch.Macht das für Sie Sinn?
quelle
Einige mögen das Folgende nützlich finden:
Ich wollte, dass Clients für jede Restaktion, die ohne Autorisierungstoken gesendet wird, auf die Anmeldeseite umgeleitet werden. Da alle meine Restaktionen auf Ajax basieren, brauchte ich eine gute generische Methode, um zur Anmeldeseite umzuleiten, anstatt die Ajax-Erfolgsfunktion zu verwenden.
Folgendes habe ich getan:
Bei jeder Ajax-Anfrage gibt mein Server eine Json 200-Antwort "NEED TO AUTHENTICATE" zurück (wenn sich der Client authentifizieren muss).
Einfaches Beispiel in Java (Serverseite):
In meinem Javascript habe ich folgenden Code hinzugefügt:
Und das war's auch schon.
quelle
Im Servlet sollten
response.setStatus(response.SC_MOVED_PERMANENTLY);
Sie den Status '301' xmlHttp senden, den Sie für eine Umleitung benötigen ...und in der $ .ajax-Funktion sollten Sie die
.toString()
Funktion nicht verwenden ..., nurif (xmlHttp.status == 301) { top.location.href = 'xxxx.jsp'; }
Das Problem ist, dass es nicht sehr flexibel ist. Sie können sich nicht entscheiden, wohin Sie umleiten möchten.
Die Umleitung durch die Servlets sollte der beste Weg sein. aber ich kann immer noch nicht den richtigen Weg finden, es zu tun.
quelle
Ich wollte mich nur an alle Ajax-Anfragen für die gesamte Seite halten. @ SuperG hat mich dazu gebracht. Folgendes habe ich erreicht:
Ich wollte speziell nach bestimmten http-Statuscodes suchen, um meine Entscheidung zu treffen. Sie können sich jedoch einfach an ajaxError binden, um etwas anderes als Erfolg zu erzielen (nur 200 vielleicht?). Ich hätte gerade schreiben können:
quelle
Wenn Sie auch die Werte übergeben möchten, können Sie auch die Sitzungsvariablen festlegen und auf Eg zugreifen: In Ihrem JSP können Sie schreiben
Und dann können Sie diesen temporären Wert in Ihrer Javascript-Variablen speichern und herumspielen
quelle
Ich hatte keinen Erfolg mit der Header-Lösung - sie wurden in meiner ajaxSuccess / ajaxComplete-Methode nie erfasst. Ich habe Stegs Antwort mit der benutzerdefinierten Antwort verwendet, aber die JS-Seite etwas geändert. Ich richte eine Methode ein, die ich in jeder Funktion aufrufe, damit ich Standard
$.get
und$.post
Methoden verwenden kann.Beispiel dafür in Gebrauch ...
quelle
Schließlich löse ich das Problem durch Hinzufügen eines benutzerdefinierten
HTTP Header
. Kurz vor der Antwort für jede Anfrage auf der Serverseite füge ich die aktuell angeforderte URL zum Header der Antwort hinzu.Mein Anwendungstyp auf dem Server ist
Asp.Net MVC
, und es hat einen guten Ort, um dies zu tun. inGlobal.asax
ich implementierte dieApplication_EndRequest
Veranstaltung so:Es funktioniert perfekt für mich! Jetzt in jeder Antwort von der
JQuery
$.post
ich habe die angefordertenurl
und auch anderen Response - Header , die als Ergebnis kommtPOST
durch Statusverfahren302
,303
....und eine andere wichtige Sache ist, dass es nicht notwendig ist, Code auf der Server- oder Client-Seite zu ändern.
und die nächste ist die Möglichkeit, auf diese Weise auf die anderen Informationen der Nachaktion wie Fehler, Nachrichten und ... zuzugreifen.
Ich habe das gepostet, vielleicht jemandem helfen :)
quelle
Ich hatte dieses Problem in einer Django-App, an der ich bastele (Haftungsausschluss: Ich bastele am Lernen und bin in keiner Weise ein Experte). Ich wollte mit jQuery ajax eine DELETE-Anforderung an eine Ressource senden, sie auf der Serverseite löschen und dann eine Umleitung zurück zur (im Grunde) Homepage senden. Als ich
HttpResponseRedirect('/the-redirect/')
vom Python-Skript aus sendete , empfing die Ajax-Methode von jQuery 200 anstelle von 302. Ich habe also eine Antwort von 300 gesendet mit:Dann habe ich die Anfrage auf dem Client mit jQuery.ajax wie folgt gesendet / bearbeitet:
Vielleicht ist die Verwendung von 300 nicht "richtig", aber zumindest hat es so funktioniert, wie ich es wollte.
PS: Das war ein großer Aufwand für die mobile Version von SO. Dummer ISP hat meine Servicestornierungsanfrage richtig gestellt, als ich mit meiner Antwort fertig war!
quelle
Sie können auch den XMLHttpRequest-Sendeprototyp einbinden. Dies funktioniert für alle Sends (jQuery / dojo / etc) mit einem Handler.
Ich habe diesen Code geschrieben, um einen abgelaufenen Fehler von 500 Seiten zu behandeln, aber er sollte genauso gut funktionieren, um eine 200-Umleitung abzufangen. Bereiten Sie den Wikipedia-Eintrag auf XMLHttpRequest onreadystatechange über die Bedeutung von readyState vor.
quelle
Außerdem möchten Sie den Benutzer wahrscheinlich auf die in den Headern angegebene URL umleiten. Endlich sieht es so aus:
UPD: Opps. Habe die gleiche Aufgabe, aber es funktioniert nicht. Mach das Zeug. Ich zeige Ihnen die Lösung, wenn ich sie finde.
quelle
Ich habe eine funktionierende Lösung mit den Antworten von @John und @Arpad Link und @RobWinch Link erhalten
Ich verwende Spring Security 3.2.9 und jQuery 1.10.2.
Erweitern Sie die Spring-Klasse, um eine 4XX-Antwort nur von AJAX-Anforderungen zu verursachen:
applicationContext-security.xml
Fügen Sie in meinen JSPs einen globalen AJAX-Fehlerbehandler hinzu, wie hier gezeigt
Entfernen Sie außerdem vorhandene Fehlerbehandlungsroutinen aus AJAX-Aufrufen auf JSP-Seiten:
Ich hoffe es hilft anderen.
Update1 Ich habe festgestellt, dass ich die Option (always-use-default-target = "true") zur Formularanmeldekonfiguration hinzufügen muss. Dies war erforderlich, da Spring, nachdem eine AJAX-Anforderung (aufgrund einer abgelaufenen Sitzung) auf die Anmeldeseite umgeleitet wurde, die vorherige AJAX-Anforderung merkt und nach der Anmeldung automatisch zu dieser umleitet. Dadurch wird der zurückgegebene JSON auf der Browserseite angezeigt. Natürlich nicht was ich will.
Update2 Verwenden Sie anstelle von
always-use-default-target="true"
@RobWinch das Beispiel zum Blockieren von AJAX-Anforderungen aus dem requstCache. Dadurch können normale Links nach der Anmeldung zu ihrem ursprünglichen Ziel umgeleitet werden, AJAX wechselt jedoch nach der Anmeldung zur Startseite.quelle