116 votes

Comment empêcher les demandes ajax de suivre les redirections en utilisant jQuery

J'utilise les fonctions jQuery ajax pour accéder à un service web, mais le serveur, au lieu de renvoyer une réponse avec un code d'état décrivant un problème, la demande est redirigée vers une page avec un en-tête 200, décrivant le problème. Je ne peux rien y changer et je dois donc résoudre le problème sur le client d'une manière ou d'une autre.

Exemple : Une demande va vers une URL qui n'est pas trouvée, je reçois donc une redirection 302 vers un autre emplacement. Une nouvelle demande est envoyée, et je reçois un 200 OK, ce qui empêche le rappel d'erreur de se déclencher.

Existe-t-il un moyen d'empêcher la demande ajax de suivre les redirections et d'invoquer à la place un callback, de préférence la méthode error. Sinon, est-il possible de détecter si une redirection a eu lieu dans le client ?

0 votes

9 votes

Il est étrange que votre backend rapporte un 302 pour un not found, au lieu d'un 404.

1 votes

105voto

Oleg Points 136406

Je trouve votre question intéressante, mais le problème dans son ensemble me semble être plutôt un malentendu. Au moins, je vais essayer d'expliquer ma compréhension du problème.

La redirection silencieuse (transparente) est la part de XMLHttpRequest (voir aquí notamment les mots "... suivre de manière transparente la réorientation..."). La norme mentionne seulement que l'agent utilisateur (le navigateur web) peut prévenir ou notifier de certains types de redirections automatiques, mais il ne fait pas partie de XMLHttpRequest . Il s'agit de la partie de la configuration du client HTTP (configuration du système d'exploitation) ou de la configuration du navigateur Web. Ainsi, jQuery.ajax ne peut pas avoir d'option permettant d'empêcher la redirection.

Vous pouvez voir que la redirection HTTP est une partie du protocole HTTP et non une partie de XMLHttpRequest . C'est donc à un autre niveau d'abstraction ou à la pile réseau. Par exemple, les données de la XMLHttpRequest peut être récupéré à partir du proxy HTTP ou du cache local du navigateur, et c'est une partie du protocole HTTP. Principalement le serveur qui fournissent les données et non le client peuvent influencer la mise en cache.

Vous pouvez comparer l'exigence de votre question avec l'exigence d'empêcher le changement de l'adresse IP du serveur web ou le changement de la route IP pendant la communication. Toutes ces choses peuvent être intéressantes dans certains scénarios, mais il y a des parties de l'architecture de l'entreprise qui ne peuvent pas être modifiées. un autre niveau de la pile de communication et ne peuvent pas être gérés par jQuery.ajax o XMLHttpRequest .

El XMLHttpRequest disent que la configuration du client peut avoir des options qui empêchent la redirection. Dans le cas du "monde Microsoft", que je connais mieux, vous pouvez regarder à WinHttpSetOption qui peut être utilisée pour définir WINHTTP_OPTION_DISABLE_FEATURE avec l'option WINHTTP_DISABLE_REDIRECTS valeur. Un autre moyen est l'utilisation de WINHTTP_OPTION_REDIRECT_POLICY avec l'option WINHTTP_OPTION_REDIRECT_POLICY_NEVER valeur. Une autre fonctionnalité que l'on peut utiliser dans Windows est la fonction WinHttpSetStatusCallback qui peut définir une fonction de rappel pour recevoir certaines notifications comme WINHTTP_CALLBACK_FLAG_REDIRECT .

Il est donc possible de mettre en œuvre vos exigences de manière générale, mais la solution ne sera probablement pas indépendante du système d'exploitation ou du navigateur web et ne sera pas au niveau de la technologie de l'information. jQuery.ajax o XMLHttpRequest .

3 votes

Excellente réponse avec une grande perspicacité ! J'ai une certaine expérience de curl, pour lequel vous pouvez définir des drapeaux similaires à ceux que vous mentionnez. J'espérais que de telles instructions pourraient être transmises au navigateur, mais d'après votre réponse, je comprends que le comportement attendu serait de suivre les redirections comme si la demande initiale était envoyée à l'emplacement attribué par le serveur.

0 votes

@Jørgen : Vous êtes le bienvenu ! Dans la plupart des scénarios, la redirection n'est pas du tout un problème. Vous ne décrivez pas le contexte dans lequel vous utilisez jQuery.ajax et si vous avez un contrôle total sur le serveur web auquel vous envoyez la requête. Il est donc difficile de vous donner d'autres conseils qui pourraient réellement résoudre votre problème.

0 votes

Je ne contrôle pas le côté serveur, j'en ai peur. Je suppose que ma meilleure option est d'analyser ou de valider le contenu de la réponse.

27voto

Jake Feasel Points 10341

Je ne crois pas que ce soit possible. La bibliothèque sous-jacente (XHR) effectue la nouvelle demande de manière transparente. Ceci étant dit, ce que j'ai fait dans ces situations (généralement un problème de type session-timeout qui m'amène à une page de connexion) est de renvoyer un en-tête de réponse personnalisé. J'ai également configuré un gestionnaire ajax global qui vérifie la présence de cet en-tête et répond de manière appropriée lorsqu'il est présent (par exemple, en redirigeant la page entière vers l'écran de connexion).

Au cas où vous seriez intéressé, voici le code jQuery que je dois surveiller pour cet en-tête personnalisé :

/* redirects main window when AJAX request indicates that the session has expired on the backend. */
function checkSession(event, xhr, ajaxOptions)
{
    if (xhr.readyState == 4)
    {
        if(xhr.getResponseHeader("Login-Screen") != null && xhr.getResponseHeader("Login-Screen").length)
        {
            window.location.href='sessionExpired.html'; //whatever
        }
    }
}

$(document).ajaxComplete(checkSession)

1 votes

Merci, je suppose que je vais devoir me contenter d'une approche similaire, en analysant la réponse.

2voto

Je ne peux pas ajouter à la sagesse perspicace des codeurs précédents qui ont répondu, mais je vais ajouter un cas spécifique que d'autres peuvent trouver utile de connaître.

Je suis tombé sur ce 302 silent redirect dans le contexte de SharePoint. J'ai un code client Javascript simple qui fait un ping sur un sous-site SharePoint, et s'il reçoit une réponse HTTP 200, il se relocalise sur ce site, par l'intermédiaire de window.location . S'il reçoit autre chose, il donne à l'utilisateur un avis indiquant que le site n'existe pas.

Cependant, dans le cas où le site existe mais que l'utilisateur n'a pas la permission, SharePoint redirige silencieusement vers une page AccessDenied.aspx. SharePoint a déjà effectué la poignée de main d'authentification HTTP 401 au niveau du serveur/de la ferme - l'utilisateur a accès à SharePoint. Mais l'accès au sous-site est géré, je suppose, à l'aide de drapeaux de base de données de quelque sorte. La redirection silencieuse contourne ma clause "else", et je ne peux donc pas créer ma propre erreur. Dans mon cas, ce n'est pas un coup d'arrêt - c'est un comportement prévisible et cohérent. Mais c'était un peu surprenant, et j'ai appris quelque chose sur les requêtes HTTP dans le processus !

0voto

netadictos Points 4988

Je suppose que vous recevez une réponse 200 parce que la deuxième fois, il n'y a pas de redirection, car la page 404 n'expire pas, elle est enregistrée dans le cache. C'est à dire que la deuxième fois le navigateur vous donne la page dans le cache. Il y a une propriété "cache" dans l'ajax jquery. http://api.jquery.com/jQuery.ajax/

Vous devriez l'écrire à "false"

-2voto

ipr101 Points 15337

Je ne suis pas sûr que cela s'applique à votre cas, mais vous pouvez écrire du code pour répondre à des codes d'état spécifiques dans la fonction AJAX.

$.ajax({
    url: '/admin/secret/data',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    statusCode: {
        200: function (data) {
            alert('302: Occurred');
            // Bind the JSON data to the UI
        },
        401: function (data) {
            alert('401: Occurred');
            // Handle the 401 error here.
        }
    }
});

9 votes

Je ne pense pas que cela s'applique parce que l'OP a dit qu'il toujours obtient un code d'état 200 en raison de la redirection qui se produit en arrière-plan

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X