Rilevamento di un reindirizzamento nella richiesta ajax?


94

Voglio usare jQuery per OTTENERE un URL e controllare esplicitamente se ha risposto con un reindirizzamento 302, ma non seguire il reindirizzamento.

$.ajaxSembra che jQuery segua sempre i reindirizzamenti. Come posso impedirlo e vedere il reindirizzamento senza seguirlo?

Ci sono varie domande con titoli come "jquery ajax redirect" ma sembrano tutte implicare il raggiungimento di qualche altro obiettivo, piuttosto che il controllo diretto dello stato fornito da un server.

Risposte:



41

Benvenuto nel futuro!

In questo momento abbiamo una proprietà "responseURL" dall'oggetto xhr. SÌÌ!

Vedi Come ottenere l'URL di risposta in XMLHttpRequest?

Tuttavia, jQuery (almeno 1.7.1) non fornisce un accesso diretto all'oggetto XMLHttpRequest. Puoi usare qualcosa del genere:

var xhr;
var _orgAjax = jQuery.ajaxSettings.xhr;
jQuery.ajaxSettings.xhr = function () {
  xhr = _orgAjax();
  return xhr;
};

jQuery.ajax('http://test.com', {
  success: function(responseText) {
    console.log('responseURL:', xhr.responseURL, 'responseText:', responseText);
  }
});

Non è una soluzione pulita e suppongo che il team di jQuery creerà qualcosa per responseURL nelle versioni future.

SUGGERIMENTO : confronta semplicemente l'URL originale con responseUrl. Se è uguale, non è stato fornito alcun reindirizzamento. Se è "undefined", probabilmente responseUrl non è supportato. Tuttavia, come ha detto Nick Garvey, la richiesta AJAX non ha mai l'opportunità di NON seguire il reindirizzamento, ma è possibile risolvere una serie di attività utilizzando la proprietà responseUrl .


1
Per aggiungere altre risorse a questo attributo - pagina MDN su XHR.responseURL - il supporto generale sembra essere in attesa su MSIE, che lo ha aggiunto solo in Edge / 14.
Eli Collins

Grazie ! Molto utile
Gautier

Ho scoperto che questo codice fa effettivamente $ .ajax ({url: 'someurl', xhrFields: {withCredentials: true}}) genera un errore in Internet Explorer perché la funzione _orgAjax dipende dalla variabile 'this' che si risolve in $ .ajaxSettings oggetto. In caso contrario, jQuery crea un oggetto IXMLHTTPRequest ActiveX invece di un oggetto XMLHttpRequest, che non supporta la proprietà withCredentials. Ho risolto questo problema chiamando xhr = _orgAjax.call ($. AjaxSettings); invece di xhr = _orgAjax (); Spero che questo aiuti qualcuno.
StephenKC

11

Mentre le altre persone che hanno risposto a questa domanda hanno (purtroppo) corretto sul fatto che queste informazioni ci sono nascoste dal browser, ho pensato di pubblicare una soluzione alternativa che ho escogitato:

Ho configurato la mia app server per impostare un'intestazione di risposta personalizzata ( X-Response-Url) contenente l'URL richiesto. Ogni volta che il mio codice ajax riceve una risposta, controlla se xhr.getResponseHeader("x-response-url")è definito, nel qual caso lo confronta con l'URL che aveva originariamente richiesto tramite $.ajax(). Se le stringhe differiscono, so che c'è stato un reindirizzamento e, inoltre, a quale URL siamo effettivamente arrivati.

Questo ha lo svantaggio di richiedere un aiuto lato server e potrebbe anche interrompersi se l'URL viene modificato (a causa di problemi di quotazione / codifica ecc.) Durante il viaggio di andata e ritorno ... ma per il 99% dei casi, questo sembra ottenere il lavoro fatto.


Sul lato server, il mio caso specifico era un'applicazione Python che utilizzava il framework web Pyramid e ho usato il seguente frammento:

import pyramid.events

@pyramid.events.subscriber(pyramid.events.NewResponse)
def set_response_header(event):
    request = event.request
    if request.is_xhr:
        event.response.headers['X-Response-URL'] = request.url

È vero infatti che non c'è modo di sapere se c'è un reindirizzamento senza prenderlo; ma forse confrontare l'URL di intestazione previsto con quello reindirizzato può essere una soluzione alternativa per me in questo momento. Grazie per l'idea
Sergio A.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.