javascript get - Come gestire una richiesta di reindirizzamento dopo una chiamata Ajax jQuery





content type (25)


Ho letto questa domanda e ho implementato l'approccio che è stato indicato per l'impostazione del codice di stato della risposta su 278 per evitare che il browser gestisca in modo trasparente i reindirizzamenti. Anche se questo ha funzionato, ero un po 'insoddisfatto in quanto è un po' un trucco.

Dopo aver scavato di più, ho abbandonato questo approccio e ho usato JSON . In questo caso, tutte le risposte alle richieste Ajax hanno il codice di stato 200 e il corpo della risposta contiene un oggetto JSON costruito sul server. Il javascript sul client può quindi utilizzare l'oggetto JSON per decidere cosa deve fare.

Ho avuto un problema simile al tuo. Eseguo una richiesta Ajax che ha 2 possibili risposte: una che reindirizza il browser a una nuova pagina e una che sostituisce un modulo HTML esistente nella pagina corrente con una nuova. Il codice jquery per fare ciò assomiglia a qualcosa:

$.ajax({
    type: "POST",
    url: reqUrl,
    data: reqBody,
    dataType: "json",
    success: function(data, textStatus) {
        if (data.redirect) {
            // data.redirect contains the string URL to redirect to
            window.location.href = data.redirect;
        }
        else {
            // data.form contains the HTML for the replacement form
            $("#myform").replaceWith(data.form);
        }
    }
});

L'oggetto JSON "data" è costruito sul server per avere 2 membri: data.redirect e data.form. Ho trovato questo approccio molto migliore.

Sto usando $.post() per chiamare un servlet usando Ajax e quindi usando il frammento HTML risultante per sostituire un elemento div nella pagina corrente dell'utente. Tuttavia, se la sessione scade, il server invia una direttiva di reindirizzamento per inviare l'utente alla pagina di accesso. In questo caso, jQuery sostituisce l'elemento div con i contenuti della pagina di accesso, costringendo gli occhi dell'utente a testimoniare una scena rara.

Come posso gestire una direttiva di reindirizzamento da una chiamata Ajax con jQuery 1.2.6?




Utilizza la chiamata $.ajax() basso livello:

$.ajax({
  url: "/yourservlet",
  data: { },
  complete: function(xmlHttp) {
    // xmlHttp is a XMLHttpRquest object
    alert(xmlHttp.status);
  }
});

Prova questo per un reindirizzamento:

if (xmlHttp.code != 200) {
  top.location.href = '/some/other/page';
}



Lasciatemi solo citare di nuovo il problema come descritto da @Steg

Ho avuto un problema simile al tuo. Eseguo una richiesta Ajax che ha 2 possibili risposte: una che reindirizza il browser a una nuova pagina e una che sostituisce un modulo HTML esistente nella pagina corrente con una nuova.

IMHO questa è una vera sfida e dovrà essere ufficialmente estesa agli attuali standard HTTP.

Credo che il nuovo standard Http utilizzerà un nuovo status-code. che significa: attualmente 301/302 dice al browser di andare a recuperare il contenuto di questa richiesta in una nuova location .

Nello standard esteso, dirà che se lo status: 308 della risposta status: 308 (solo un esempio), il browser dovrebbe reindirizzare la pagina principale nella location fornita.

Detto ciò; Sono propenso a imitare già questo comportamento futuro , e quindi quando è necessario un documento.redirect, ho il server rispondere come:

status: 204 No Content
x-status: 308 Document Redirect
x-location: /login.html

Quando JS ottiene lo " status: 204 ", controlla l'esistenza dell'intestazione x-status: 308 e esegue un document.redirect sulla pagina fornita nell'intestazione della location .

Ha senso per te?




La maggior parte delle soluzioni fornite utilizza una soluzione alternativa, utilizzando un'intestazione aggiuntiva o un codice HTTP inappropriato. Queste soluzioni funzioneranno molto probabilmente, ma si sentiranno un po '"hacky". Ho trovato un'altra soluzione.

Stiamo usando WIF che è configurato per il reindirizzamento (passiveRedirectEnabled = "true") su una risposta 401. Il reindirizzamento è utile quando si gestiscono le richieste normali ma non funzionerà per le richieste AJAX (poiché i browser non eseguiranno il 302 / reindirizzamento).

Usando il seguente codice nel tuo global.asax puoi disabilitare il reindirizzamento per le richieste AJAX:

    void WSFederationAuthenticationModule_AuthorizationFailed(object sender, AuthorizationFailedEventArgs e)
    {
        string requestedWithHeader = HttpContext.Current.Request.Headers["X-Requested-With"];

        if (!string.IsNullOrEmpty(requestedWithHeader) && requestedWithHeader.Equals("XMLHttpRequest", StringComparison.OrdinalIgnoreCase))
        {
            e.RedirectToIdentityProvider = false;
        }
    }

Ciò ti consente di restituire 401 risposte per richieste AJAX, che il tuo javascript può gestire ricaricando la pagina. Ricaricare la pagina genererà un 401 che sarà gestito da WIF (e WIF reindirizzerà l'utente alla pagina di login).

Un esempio di javascript per gestire gli errori 401:

$(document).ajaxError(function (event, jqxhr, settings, exception) {

    if (jqxhr.status == 401) { //Forbidden, go to login
        //Use a reload, WIF will redirect to Login
        location.reload(true);
    }
});



Ho risolto questo problema in questo modo:

Aggiungere un middleware per elaborare la risposta, se si tratta di un reindirizzamento per una richiesta Ajax, modificare la risposta a una risposta normale con l'url di reindirizzamento.

class AjaxRedirect(object):
  def process_response(self, request, response):
    if request.is_ajax():
      if type(response) == HttpResponseRedirect:
        r = HttpResponse(json.dumps({'redirect': response['Location']}))
        return r
    return response

Quindi, in ajaxComplete, se la risposta contiene reindirizzamento, deve essere un reindirizzamento, quindi modificare la posizione del browser.

$('body').ajaxComplete(function (e, xhr, settings) {
   if (xhr.status == 200) {
       var redirect = null;
       try {
           redirect = $.parseJSON(xhr.responseText).redirect;
           if (redirect) {
               window.location.href = redirect.replace(/\?.*$/, "?next=" + window.location.pathname);
           }
       } catch (e) {
           return;
       }
   }
}



Nessun browser gestisce correttamente le risposte 301 e 302. E in effetti lo standard dice anche che dovrebbero gestirli "in modo trasparente", che è un enorme mal di testa per i venditori della libreria Ajax. In Ra-Ajax siamo stati costretti a utilizzare il codice di stato della risposta HTTP 278 (solo un codice di successo "non utilizzato") per gestire reindirizzamenti trasparenti dal server ...

Questo mi infastidisce davvero, e se qualcuno qui ha qualche "strappo" nel W3C, mi farebbe piacere che tu possa far sapere al W3C che abbiamo davvero bisogno di gestire noi stessi i codici 301 e 302 ...! ;)




nel servlet dovresti inserire response.setStatus(response.SC_MOVED_PERMANENTLY); per inviare lo stato xmlHttp '301' di cui hai bisogno per un reindirizzamento ...

e nella funzione $ .ajax non dovresti usare la funzione .toString() ..., giusto

if (xmlHttp.status == 301) { top.location.href = 'xxxx.jsp'; }

il problema è che non è molto flessibile, non puoi decidere dove vuoi reindirizzare ..

il reindirizzamento attraverso i servlet dovrebbe essere il modo migliore. ma non riesco ancora a trovare il modo giusto per farlo.




Volevo solo condividere il mio approccio in quanto ciò potrebbe aiutare qualcuno:

Fondamentalmente ho incluso un modulo JavaScript che gestisce le cose di autenticazione come la visualizzazione del nome utente e anche questo caso che gestisce il reindirizzamento alla pagina di accesso .

Il mio scenario: fondamentalmente abbiamo un server ISA in mezzo che ascolta tutte le richieste e risponde con un'intestazione 302 e una posizione alla nostra pagina di accesso.

Nel mio modulo JavaScript il mio approccio iniziale era qualcosa di simile

$(document).ajaxComplete(function(e, xhr, settings){
    if(xhr.status === 302){
        //check for location header and redirect...
    }
});

Il problema (come molti già menzionato) è che il browser gestisce il reindirizzamento da solo, quindi il mio callback ajaxComplete non è mai stato chiamato, ma invece ho ricevuto la risposta della pagina di login già reindirizzata che ovviamente era status 200 . Il problema: come si rileva se la risposta di successo 200 è la tua pagina di login effettiva o solo qualche altra pagina arbitraria ??

La soluzione

Poiché non sono stato in grado di acquisire le risposte di reindirizzamento 302, ho aggiunto un'intestazione LoginPage sulla mia pagina di accesso che conteneva l'url della pagina di accesso stessa. Nel modulo ora ascolto l'intestazione e faccio un reindirizzamento:

if(xhr.status === 200){
    var loginPageRedirectHeader = xhr.getResponseHeader("LoginPage");
    if(loginPageRedirectHeader && loginPageRedirectHeader !== ""){
        window.location.replace(loginPageRedirectHeader);
    }
}

... e funziona come un fascino :). Potresti LoginPage perché includo l'url nell'intestazione LoginPage ... in pratica perché non ho trovato alcun modo di determinare l'url di GET risultante dal reindirizzamento automatico della posizione dall'oggetto xhr ...




Ho risolto questo problema con:

  1. Aggiunta di un'intestazione personalizzata alla risposta:

    public ActionResult Index(){
        if (!HttpContext.User.Identity.IsAuthenticated)
        {
            HttpContext.Response.AddHeader("REQUIRES_AUTH","1");
        }
        return View();
    }
    
  2. ajaxSuccess una funzione JavaScript all'evento ajaxSuccess e verifica se l'intestazione esiste:

    $(document).ajaxSuccess(function(event, request, settings) {
        if (request.getResponseHeader('REQUIRES_AUTH') === '1') {
           window.location = '/';
        }
    });
    



Se vuoi anche passare i valori, puoi anche impostare le variabili di sessione e accedere ad Eg: Nel tuo jsp puoi scrivere

<% HttpSession ses = request.getSession(true);
   String temp=request.getAttribute("what_you_defined"); %>

E poi puoi memorizzare questo valore temporaneo nella tua variabile javascript e giocare




Infine, risolvo il problema aggiungendo un'abitudine HTTP Header. Appena prima della risposta per ogni richiesta sul lato server, aggiungo l'url richiesto corrente all'intestazione della risposta.

Il mio tipo di applicazione sul server è Asp.Net MVC, e ha un buon posto per farlo. in Global.asaxho implementato l' Application_EndRequestevento così:

    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);
        }

    }

Funziona perfettamente per me! Ora, in ogni risposta della JQuery $.postho la richiesta urle anche altri intestazioni di risposta, che si presenta come risultato di POSTmetodo in base allo stato 302, 303, ....

e altra cosa importante è che non è necessario modificare il codice lato server o lato client.

e la prossima è la possibilità di ottenere l'accesso alle altre informazioni di post azione come errori, messaggi e ..., In questo modo.

Ho postato questo, forse aiutare qualcuno :)




Ho ottenuto un solulion di lavoro utilizzando le risposte da @ John e @Arpad .com/a/8426947/4505142 e @RobWinch link

Io uso Spring Security 3.2.9 e jQuery 1.10.2.

Estendi la classe di Spring per causare la risposta 4XX solo dalle richieste AJAX:

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>

Nei miei JSP, aggiungi un gestore di errori AJAX globale come mostrato here

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

Inoltre, rimuovi i gestori di errori esistenti dalle chiamate AJAX nelle pagine JSP:

        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");
//            }
        });

Spero che aiuti gli altri.

Update1 Ho scoperto che avevo bisogno di aggiungere l'opzione (always-use-default-target = "true") alla configurazione di login form. Ciò era necessario poiché dopo che una richiesta AJAX viene reindirizzata alla pagina di accesso (a causa della sessione scaduta), Spring ricorda la precedente richiesta AJAX e reindirizza automaticamente ad essa dopo l'accesso. Ciò fa sì che il JSON restituito venga visualizzato nella pagina del browser. Certo, non quello che voglio.

Update2 Invece di usare always-use-default-target="true", usa @RobWinch esempio di blocco delle richieste AJAX da requstCache. Ciò consente ai collegamenti normali di essere reindirizzati al loro target originale dopo il login, ma AJAX va alla home page dopo il login.




Mi piace il metodo di Timmerz con un leggero tocco di limone. Se vieni restituito contentType di text / html quando sei in attesa di JSON , molto probabilmente verrai reindirizzato. Nel mio caso, semplicemente ricarico la pagina e viene reindirizzato alla pagina di accesso. Oh, e controlla che lo stato di jqXHR sia 200, il che sembra sciocco, perché sei nella funzione di errore, giusto? In caso contrario, i casi di errore legittimi imporranno un ricaricamento iterativo (oops)

$.ajax(
   error:  function (jqXHR, timeout, message) {
    var contentType = jqXHR.getResponseHeader("Content-Type");
    if (jqXHR.status === 200 && contentType.toLowerCase().indexOf("text/html") >= 0) {
        // assume that our login has expired - reload our current page
        window.location.reload();
    }

});



Ho una soluzione semplice che funziona per me, nessun cambio di codice del server necessario ... basta aggiungere un cucchiaino di noce moscata ...

$(document).ready(function ()
{
    $(document).ajaxSend(
    function(event,request,settings)
    {
        var intercepted_success = settings.success;
        settings.success = function( a, b, c ) 
        {  
            if( request.responseText.indexOf( "<html>" ) > -1 )
                window.location = window.location;
            else
                intercepted_success( a, b, c );
        };
    });
});

Controllo la presenza del tag html, ma puoi modificare indexOf per cercare qualsiasi stringa univoca esistente nella tua pagina di accesso ...




Inoltre, probabilmente vorrai reindirizzare l'utente all'URL specificato. Quindi alla fine assomiglierà a questo:

$.ajax({
    //.... other definition
    complete:function(xmlHttp){
        if(xmlHttp.status.toString()[0]=='3'){
        top.location.href = xmlHttp.getResponseHeader('Location');
    }
});

UPD: Opps. Hanno lo stesso compito, ma non funziona. Facendo questa roba Ti mostrerò una soluzione quando la troverò.




Volevo solo aggrapparmi a qualsiasi richiesta di ajax per l'intera pagina. @SuperG mi ha fatto iniziare. Ecco cosa ho finito con:

// redirect ajax requests that are redirected, not found (404), or forbidden (403.)
$('body').bind('ajaxComplete', function(event,request,settings){
        switch(request.status) {
            case 301: case 404: case 403:                    
                window.location.replace("http://mysite.tld/login");
                break;
        }
});

Volevo verificare in particolare determinati codici di stato http per basare la mia decisione su. Tuttavia, puoi semplicemente associare a ajaxError per ottenere qualcosa di diverso dal successo (solo 200 forse?) Potrei aver appena scritto:

$('body').bind('ajaxError', function(event,request,settings){
    window.location.replace("http://mysite.tld/login");
}



Provare

    $(document).ready(function () {
        if ($("#site").length > 0) {
            window.location = "<%= Url.Content("~") %>" + "Login/LogOn";
        }
    });

Mettilo nella pagina di accesso. Se è stato caricato in un div sulla pagina principale, verrà reindirizzato alla pagina di accesso. "#site" è un ID di un div che si trova su tutte le pagine ad eccezione della pagina di accesso.




Sebbene le risposte sembrino funzionare per le persone se si sta utilizzando Spring Security, ho trovato l'estensione di LoginUrlAuthenticationEntryPoint e l'aggiunta di codice specifico per gestire AJAX più robusto. La maggior parte degli esempi intercetta tutti i reindirizzamenti, non solo quelli di autenticazione. Questo non era auspicabile per il progetto su cui lavoro. È possibile che sia necessario estendere ExceptionTranslationFilter e sovrascrivere il metodo "sendStartAuthentication" per rimuovere il passaggio di memorizzazione nella cache se non si desidera memorizzare la richiesta AJAX memorizzata nella cache.

Esempio AjaxAwareAuthenticationEntryPoint:

public class AjaxAwareAuthenticationEntryPoint extends
    LoginUrlAuthenticationEntryPoint {

    public AjaxAwareAuthenticationEntryPoint(String loginUrl) {
        super(loginUrl);
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        if (isAjax(request)) {
            response.sendError(HttpStatus.UNAUTHORIZED.value(), "Please re-authenticate yourself");
        } else {
        super.commence(request, response, authException);
        }
    }

    public static boolean isAjax(HttpServletRequest request) {
        return request != null && "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }
}

Fonti: 1 , 2




    <script>
    function showValues() {
        var str = $("form").serialize();
        $.post('loginUser.html', 
        str,
        function(responseText, responseStatus, responseXML){
            if(responseStatus=="success"){
                window.location= "adminIndex.html";
            }
        });     
    }
</script>



Non ho avuto alcun successo con la soluzione di intestazione - non sono mai stati rilevati nel mio metodo ajaxSuccess / ajaxComplete. Ho usato la risposta di Steg con la risposta personalizzata, ma ho modificato il lato JS. Ho impostato un metodo che chiamo in ciascuna funzione in modo da poter utilizzare standard $.gete $.postmetodi.

function handleAjaxResponse(data, callback) {
    //Try to convert and parse object
    try {
        if (jQuery.type(data) === "string") {
            data = jQuery.parseJSON(data);
        }
        if (data.error) {
            if (data.error == 'login') {
                window.location.reload();
                return;
            }
            else if (data.error.length > 0) {
                alert(data.error);
                return;
            }
        }
    }
    catch(ex) { }

    if (callback) {
        callback(data);
    }
}

Esempio in uso ...

function submitAjaxForm(form, url, action) {
    //Lock form
    form.find('.ajax-submit').hide();
    form.find('.loader').show();

    $.post(url, form.serialize(), function (d) {
        //Unlock form
        form.find('.ajax-submit').show();
        form.find('.loader').hide();

        handleAjaxResponse(d, function (data) {
            // ... more code for if auth passes ...
        });
    });
    return false;
}



Alcuni potrebbero trovare il sotto utile:

Volevo che i client venissero reindirizzati alla pagina di login per ogni rest-action che viene inviata senza un token di autorizzazione. Poiché tutte le mie rest-action sono basate su Ajax, avevo bisogno di un buon modo generico per reindirizzare alla pagina di login invece di gestire la funzione di successo Ajax.

Questo è quello che ho fatto:

Su qualsiasi richiesta Ajax, il mio server restituirà una risposta JSON 200 "NECESSITÀ DI AUTENTICARE" (se il client deve autenticarsi).

Semplice esempio in Java (lato server):

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    private final Logger m_logger = LoggerFactory.getLogger(AuthenticationFilter.class);

    public static final String COOKIE_NAME = "token_cookie"; 

    @Override
    public void filter(ContainerRequestContext context) throws IOException {        
        // Check if it has a cookie.
        try {
            Map<String, Cookie> cookies = context.getCookies();

            if (!cookies.containsKey(COOKIE_NAME)) {
                m_logger.debug("No cookie set - redirect to login page");
                throw new AuthenticationException();
            }
        }
        catch (AuthenticationException e) {
            context.abortWith(Response.ok("\"NEED TO AUTHENTICATE\"").type("json/application").build());
        }
    }
}

Nel mio Javascript ho aggiunto il seguente codice:

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    var originalSuccess = options.success;

    options.success = function(data) {
        if (data == "NEED TO AUTHENTICATE") {
            window.location.replace("/login.html");
        }
        else {
            originalSuccess(data);
        }
    };      
});

E questo è tutto.




So che questo argomento è vecchio, ma darò un altro approccio che ho trovato e precedentemente descritto here . Fondamentalmente sto usando ASP.MVC con WIF (ma questo non è molto importante per il contesto di questo argomento - la risposta è adeguata indipendentemente dal framework utilizzato. L'indizio rimane invariato, trattando i problemi relativi agli errori di autenticazione durante l'esecuzione delle richieste Ajax ) .

L'approccio mostrato di seguito può essere applicato a tutte le richieste ajax out of the box (se non ridefiniscono ovviamente l'evento beforeSend).

$.ajaxSetup({
    beforeSend: checkPulse,
    error: function (XMLHttpRequest, textStatus, errorThrown) {
        document.open();
        document.write(XMLHttpRequest.responseText);
        document.close();
    }
});

Prima di ogni richiesta CheckPulse viene eseguito il metodo CheckPulse (il metodo controller che può essere qualsiasi cosa più semplice):

[Authorize]
public virtual void CheckPulse() {}

Se l'utente non è autenticato (il token è scaduto) non è possibile accedere a tale metodo (protetto da attributo Authorize ). Poiché il framework gestisce l'autenticazione, mentre il token scade, inserisce lo stato http 302 nella risposta. Se non si desidera che il browser gestisca in modo trasparente la risposta 302, acquisirla in Global.asax e modificare lo stato della risposta, ad esempio 200 OK. Inoltre, aggiungi l'intestazione, che ti indica di elaborare tale risposta in modo speciale (più avanti sul lato client):

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 302
        && (new HttpContextWrapper(Context)).Request.IsAjaxRequest())
    {                
        Context.Response.StatusCode = 200;
        Context.Response.AddHeader("REQUIRES_AUTH", "1");
    }
}

Infine, dal lato client, controlla l'intestazione personalizzata. Se presente, deve essere eseguito il reindirizzamento completo alla pagina di accesso (nel mio caso window.location viene sostituito window.location dalla richiesta che viene gestito automaticamente dal mio framework).

function checkPulse(XMLHttpRequest) {
    var location = window.location.href;
    $.ajax({
        url: "/Controller/CheckPulse",
        type: 'GET',
        async: false,
        beforeSend: null,
        success:
            function (result, textStatus, xhr) {
                if (xhr.getResponseHeader('REQUIRES_AUTH') === '1') {
                    XMLHttpRequest.abort(); // terminate further ajax execution
                    window.location = location;
                }
            }
    });
}



Questo problema può essere visualizzato utilizzando il metodo RedirectToAction di ASP.NET MVC. Per evitare che il modulo mostri la risposta in div, puoi semplicemente fare un qualche tipo di filtro di risposta ajax per le risposte in entrata con $ .ajaxSetup . Se la risposta contiene il reindirizzamento MVC, è possibile valutare questa espressione sul lato JS. Esempio di codice per JS di seguito:

$.ajaxSetup({
    dataFilter: function (data, type) {
        if (data && typeof data == "string") {
            if (data.indexOf('window.location') > -1) {
                eval(data);
            }
        }
        return data;
    }
});

Se i dati sono: "window.location = '/ Acount / Login'" sopra il filtro lo prenderà e valuterà di effettuare il reindirizzamento invece di lasciare che i dati vengano visualizzati.




La soluzione che è stata infine implementata era quella di utilizzare un wrapper per la funzione di callback della chiamata Ajax e in questo wrapper verificare l'esistenza di un elemento specifico sul blocco HTML restituito. Se l'elemento è stato trovato, il wrapper eseguiva un reindirizzamento. In caso contrario, il wrapper ha inoltrato la chiamata alla funzione di callback effettiva.

Ad esempio, la nostra funzione wrapper era qualcosa del tipo:

function cbWrapper(data, funct){
    if($("#myForm", data).length > 0)
        top.location.href="login.htm";//redirection
    else
        funct(data);
}

Quindi, durante la chiamata Ajax, abbiamo usato qualcosa come:

$.post("myAjaxHandler", 
       {
        param1: foo,
        param2: bar
       },
       function(data){
           cbWrapper(data, myActualCB);
       }, 
       "html"
);

Questo ha funzionato per noi perché tutte le chiamate Ajax hanno sempre restituito l'HTML all'interno di un elemento DIV che usiamo per sostituire un pezzo della pagina. Inoltre, abbiamo solo bisogno di reindirizzare alla pagina di accesso.




Non hai bisogno di jQuery per questo

In Vanilla puoi fare:

document.querySelectorAll('.a.b')




javascript jquery ajax redirect