Détecter une redirection dans une requête ajax?

94

Je veux utiliser jQuery pour OBTENIR une URL et vérifier explicitement s'il a répondu avec une redirection 302, mais ne pas suivre la redirection.

jQuery $.ajaxsemble toujours suivre les redirections. Comment puis-je éviter cela et voir la redirection sans la suivre?

Il y a diverses questions avec des titres comme "jquery ajax redirect" mais elles semblent toutes impliquer l'accomplissement d'un autre objectif, plutôt que de simplement vérifier directement l'état d'un serveur.

kdt
la source

Réponses:

87

La requête AJAX n'a ​​jamais la possibilité de NE PAS suivre la redirection (c'est-à-dire qu'elle doit suivre la redirection). Plus d'informations peuvent être trouvées dans cette réponse https://stackoverflow.com/a/2573589/965648

Nick Garvey
la source
41

Bienvenue dans le futur!

À l'heure actuelle, nous avons une propriété "responseURL" de l'objet xhr. YAY!

Consultez Comment obtenir l'url de réponse dans XMLHttpRequest?

Cependant, jQuery (au moins 1.7.1) ne donne pas d'accès directement à l'objet XMLHttpRequest. Vous pouvez utiliser quelque chose comme ceci:

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

Ce n'est pas une solution propre et je suppose que l'équipe jQuery fera quelque chose pour responseURL dans les prochaines versions.

CONSEIL : comparez simplement l'URL d'origine avec responseUrl. Si c'est égal, aucune redirection n'a été donnée. S'il est "indéfini", responseUrl n'est probablement pas pris en charge. Cependant, comme l'a dit Nick Garvey, la requête AJAX n'a ​​jamais la possibilité de NE PAS suivre la redirection, mais vous pouvez résoudre un certain nombre de tâches en utilisant la propriété responseUrl .

Riki_tiki_tavi
la source
1
Pour ajouter plus de ressources sur cet attribut - page MDN sur XHR.responseURL - le support général semble attendre sur MSIE, qui l'a seulement ajouté dans Edge / 14.
Eli Collins
Merci ! Very usefull
Gautier
J'ai trouvé que ce code fait en fait $ .ajax ({url: 'someurl', xhrFields: {withCredentials: true}}) lancer une erreur dans Internet Explorer car la fonction _orgAjax dépend de la variable 'this' résolvant le $ .ajaxSettings objet. Quand ce n'est pas le cas, jQuery crée un objet ActiveX IXMLHTTPRequest au lieu d'un objet XMLHttpRequest, qui ne prend pas en charge la propriété withCredentials. J'ai corrigé cela en appelant xhr = _orgAjax.call ($. AjaxSettings); au lieu de xhr = _orgAjax (); J'espère que ça aidera quelqu'un.
StephenKC
11

Alors que les autres personnes qui ont répondu à cette question ont (malheureusement) raison de dire que ces informations nous sont cachées par le navigateur, j'ai pensé publier une solution de contournement que j'ai trouvée:

J'ai configuré mon application serveur pour définir un en-tête de réponse personnalisé ( X-Response-Url) contenant l'URL demandée. Chaque fois que mon code ajax reçoit une réponse, il vérifie si xhr.getResponseHeader("x-response-url")est défini, auquel cas il le compare à l'url qu'il a initialement demandé via $.ajax(). Si les chaînes diffèrent, je sais qu'il y a eu une redirection et, en plus, à quelle URL nous sommes arrivés.

Cela a l'inconvénient de nécessiter une aide côté serveur, et peut également tomber en panne si l'URL est mungée (en raison de problèmes de citation / d'encodage, etc.) pendant l'aller-retour ... mais dans 99% des cas, cela semble se produire le travail accompli.


Côté serveur, mon cas spécifique était une application python utilisant le framework Web Pyramid, et j'ai utilisé l'extrait de code suivant:

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
Eli Collins
la source
Il est vrai en effet qu'il n'y a aucun moyen de savoir s'il y a une redirection sans la prendre; mais peut-être que comparer l'URL d'en-tête attendue avec l'URL redirigée peut être une solution de contournement pour moi en ce moment. Merci pour l'idée
Sergio A.
4

Vous pouvez maintenant utiliser Fetch API / Il renvoieredirected: *boolean*

fvrab
la source