1532 Stimmen

Wie man eine Umleitungsanfrage nach einem jQuery Ajax-Aufruf verwaltet

Ich benutze $.post() um ein Servlet mit Ajax aufzurufen und dann das resultierende HTML-Fragment zu verwenden, um eine div Element auf der aktuellen Seite des Benutzers. Wenn die Sitzung jedoch beendet wird, sendet der Server eine Umleitungsanweisung, um den Benutzer zur Anmeldeseite zu schicken. In diesem Fall ersetzt jQuery das div Element mit dem Inhalt der Anmeldeseite und zwingt die Augen des Benutzers zu einem seltenen Anblick.

Wie kann ich eine Redirect-Direktive aus einem Ajax-Aufruf mit jQuery 1.2.6 verwalten?

1 Stimmen

(nicht eine Antwort als solche) - Ich habe dies in der Vergangenheit durch Bearbeiten der Jquery-Bibliothek und Hinzufügen einer Prüfung für die Login-Seite auf jedem XHR abgeschlossen getan. Nicht die beste Lösung, weil es jedes Mal getan werden müsste, wenn Sie aktualisieren, aber es löst das Problem.

1 Stimmen

Siehe dazugehörige Frage: stackoverflow.com/questions/5941933/

0 Stimmen

El HttpContext.Response.AddHeader und prüfen Sie den Erfolg von ajaxsetup

5voto

Ali Adlavaran Punkte 3509

Schließlich löse ich das Problem durch Hinzufügen einer benutzerdefinierten HTTP Header . Kurz vor der Antwort für jede Anforderung auf der Serverseite, füge ich die aktuelle angeforderte URL in den Header der Antwort ein.

Mein Anwendungstyp auf dem Server ist Asp.Net MVC und es hat einen guten Platz dafür. in Global.asax Ich habe die Application_EndRequest Ereignis so:

    public class MvcApplication : System.Web.HttpApplication
    {

    //  ...
    //  ...

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            var app = (HttpApplication)sender;
            app.Context.Response.Headers.Add("CurrentUrl",app.Context. Request.CurrentExecutionFilePath);
        }

    }

Für mich funktioniert es perfekt! Jetzt in jeder Antwort des JQuery $.post Ich habe die gewünschte url und auch andere Antwort-Header, die als Ergebnis von POST Methode nach Status 302 , 303 ,... .

und ein weiterer wichtiger Punkt ist, dass der Code weder auf der Server- noch auf der Client-Seite geändert werden muss.

und die nächste ist die Fähigkeit, Zugang zu den anderen Informationen der Post-Aktion wie Fehler, Nachrichten, und ..., Auf diese Weise zu erhalten.

Ich habe dies gepostet, vielleicht hilft es jemandem :)

4voto

Curtis Yallop Punkte 5900

Sie können auch Haken XMLHttpRequest senden Prototyp. Dies wird für alle sendet (jQuery/Dojo/etc) mit einem Handler arbeiten.

Ich habe diesen Code geschrieben, um einen 500 page expired error zu behandeln, aber er sollte genauso gut funktionieren, um einen 200 redirect abzufangen. Bereiten Sie den Wikipedia-Eintrag über XMLHttpRequest onreadystatechange über die Bedeutung von readyState.

// Hook XMLHttpRequest
var oldXMLHttpRequestSend = XMLHttpRequest.prototype.send;

XMLHttpRequest.prototype.send = function() {
  //console.dir( this );

  this.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 500 && this.responseText.indexOf("Expired") != -1) {
      try {
        document.documentElement.innerHTML = this.responseText;
      } catch(error) {
        // IE makes document.documentElement read only
        document.body.innerHTML = this.responseText;
      }
    }
  };

  oldXMLHttpRequestSend.apply(this, arguments);
}

4voto

Benny Jobigan Punkte 4805

Ich hatte dieses Problem auf einem Django app ich bin Basteln mit (Haftungsausschluss: Ich bin Basteln zu lernen, und bin in keiner Weise ein Experte). Was ich tun wollte, war jQuery Ajax verwenden, um eine DELETE-Anfrage an eine Ressource zu senden, löschen Sie es auf der Server-Seite, dann senden Sie eine Umleitung zurück zu (im Grunde) die Homepage. Wenn ich sendete HttpResponseRedirect('/the-redirect/') aus dem Python-Skript, erhielt die Ajax-Methode von jQuery 200 statt 302. Also, was ich tat, war eine Antwort von 300 mit zu senden:

response = HttpResponse(status='300')
response['Location'] = '/the-redirect/' 
return  response

Dann habe ich die Anforderung auf dem Client mit jQuery.ajax wie folgt gesendet/behandelt:

<button onclick="*the-jquery*">Delete</button>

where *the-jquery* =
$.ajax({ 
  type: 'DELETE', 
  url: '/resource-url/', 
  complete: function(jqxhr){ 
    window.location = jqxhr.getResponseHeader('Location'); 
  } 
});

Vielleicht ist die Verwendung von 300 nicht "richtig", aber zumindest hat es so funktioniert, wie ich es wollte.

PS: Es war sehr mühsam, dies auf der mobilen Version von SO zu bearbeiten. Der blöde Internetanbieter hat meinen Antrag auf Stornierung des Dienstes gerade dann durchgegeben, als ich mit meiner Antwort fertig war!

2voto

Eugen Konkov Punkte 18206

Als Alternative zu ajax gibt es eine neue API abrufen entwickelt, die eine manuelle Umleitung ermöglicht. Sie müssen prüfen ob die derzeitige Browserunterstützung für Ihre Bedürfnisse ausreichend ist.

2voto

Darren Parker Punkte 1572

Ich habe eine funktionierende Lösung mit den Antworten von @John und @Arpad Link und @RobWinch Link

Ich verwende Spring Security 3.2.9 und jQuery 1.10.2.

Erweitern Sie die Klasse von Spring, um 4XX-Antworten nur von AJAX-Anfragen zu erhalten:

public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    public CustomLoginUrlAuthenticationEntryPoint(final String loginFormUrl) {
        super(loginFormUrl);
    }

    // For AJAX requests for user that isn't logged in, need to return 403 status.
    // For normal requests, Spring does a (302) redirect to login.jsp which the browser handles normally.
    @Override
    public void commence(final HttpServletRequest request,
                         final HttpServletResponse response,
                         final AuthenticationException authException)
            throws IOException, ServletException {
        if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
        } else {
            super.commence(request, response, authException);
        }
    }
}

applicationContext-security.xml

  <security:http auto-config="false" use-expressions="true" entry-point-ref="customAuthEntryPoint" >
    <security:form-login login-page='/login.jsp' default-target-url='/index.jsp'                             
                         authentication-failure-url="/login.jsp?error=true"
                         />    
    <security:access-denied-handler error-page="/errorPage.jsp"/> 
    <security:logout logout-success-url="/login.jsp?logout" />
...
    <bean id="customAuthEntryPoint" class="com.myapp.utils.CustomLoginUrlAuthenticationEntryPoint" scope="singleton">
        <constructor-arg value="/login.jsp" />
    </bean>
...
<bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache">
    <property name="requestMatcher">
      <bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher">
        <constructor-arg>
          <bean class="org.springframework.security.web.util.matcher.MediaTypeRequestMatcher">
            <constructor-arg>
              <bean class="org.springframework.web.accept.HeaderContentNegotiationStrategy"/>
            </constructor-arg>
            <constructor-arg value="#{T(org.springframework.http.MediaType).APPLICATION_JSON}"/>
            <property name="useEquals" value="true"/>
          </bean>
        </constructor-arg>
      </bean>
    </property>
</bean>

Fügen Sie in meinen JSPs einen globalen AJAX-Fehler-Handler wie folgt hinzu aquí

  $( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
      if ( jqxhr.status === 403 ) {
          window.location = "login.jsp";
      } else {
          if(thrownError != null) {
              alert(thrownError);
          } else {
              alert("error");
          }
      }
  });

Entfernen Sie außerdem vorhandene Fehlerbehandlungsprogramme aus AJAX-Aufrufen in JSP-Seiten:

        var str = $("#viewForm").serialize();
        $.ajax({
            url: "get_mongoDB_doc_versions.do",
            type: "post",
            data: str,
            cache: false,
            async: false,
            dataType: "json",
            success: function(data) { ... },
//            error: function (jqXHR, textStatus, errorStr) {
//                 if(textStatus != null)
//                     alert(textStatus);
//                 else if(errorStr != null)
//                     alert(errorStr);
//                 else
//                     alert("error");
//            }
        });

Ich hoffe, es hilft anderen.

Aktualisierung1 Ich fand heraus, dass ich die Option (always-use-default-target="true") in die form-login-Konfiguration aufnehmen musste. Dies war notwendig, da Spring, nachdem eine AJAX-Anfrage auf die Anmeldeseite umgeleitet wurde (aufgrund einer abgelaufenen Sitzung), sich die vorherige AJAX-Anfrage merkt und nach der Anmeldung automatisch dorthin umleitet. Dies führt dazu, dass das zurückgegebene JSON auf der Browserseite angezeigt wird. Das ist natürlich nicht das, was ich will.

Aktualisierung2 Anstelle der Verwendung von always-use-default-target="true" Verwenden Sie @RobWinch Beispiel der Blockierung von AJAX-Anfragen aus dem requstCache. Dadurch können normale Links nach der Anmeldung zu ihrem ursprünglichen Ziel umgeleitet werden, aber AJAX-Anfragen gehen nach der Anmeldung auf die Startseite.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X