web-dev-qa-db-fra.com

En-tête de réponse jQuery et AJAX

J'ai donc cet appel jQuery AJAX, et la réponse provient du serveur sous la forme d'une redirection 302. J'aimerais prendre cette redirection et la charger dans une iframe, mais lorsque j'essaie d'afficher les informations d'en-tête avec une alerte javascript, la valeur null s'affiche même si firebug la voit correctement.

Voici le code, si cela peut aider:

$j.ajax({
    type: 'POST',
    url:'url.do',
    data: formData,
    complete: function(resp){
        alert(resp.getAllResponseHeaders());
    }
});

Je n'ai pas vraiment accès aux ressources côté serveur pour déplacer l'URL vers le corps de la réponse, ce qui, à mon avis, serait la solution la plus simple. Par conséquent, toute aide relative à l'analyse syntaxique de l'en-tête serait fantastique.

151
Shane

la solution de cballou fonctionnera si vous utilisez une ancienne version de jquery. Dans les nouvelles versions, vous pouvez également essayer:

  $.ajax({
   type: 'POST',
   url:'url.do',
   data: formData,
   success: function(data, textStatus, request){
        alert(request.getResponseHeader('some_header'));
   },
   error: function (request, textStatus, errorThrown) {
        alert(request.getResponseHeader('some_header'));
   }
  });

Selon docs l'objet XMLHttpRequest est disponible à partir de jQuery 1.4.

168
rovsen

S'il s'agit d'une demande CORS , vous pouvez voir tous les en-têtes dans les outils de débogage (tels que Chrome-> Inspecter un élément-> Réseau), mais l'objet xHR ne récupérera que l'en-tête (via xhr.getResponseHeader('Header')) si un tel en-tête est un en-tête de réponse simple :

  • Content-Type
  • Last-modified
  • Content-Language
  • Cache-Control
  • Expires
  • Pragma

S'il ne fait pas partie de cet ensemble, il doit être présent dans l'en-tête Access-Control-Expose-Headers renvoyé par le serveur.

Concernant le cas en question, s’il s’agit d’une demande CORS, on ne pourra récupérer l’en-tête Location que via l’objet XMLHttpRequest si et seulement si l’en-tête ci-dessous est également présent:

Access-Control-Expose-Headers: Location

Si ce n'est pas une demande CORS, XMLHttpRequest n'aura aucun problème à la récupérer.

129
acdcjunior
 var geturl;
  geturl = $.ajax({
    type: "GET",
    url: 'http://....',
    success: function () {
      alert("done!"+ geturl.getAllResponseHeaders());
    }
  });
31
keithics

La triste vérité sur AJAX et la redirection 302 est que vous ne pouvez pas obtenir les en-têtes de la déclaration car le navigateur ne les attribue jamais à XHR. Lorsqu'un navigateur voit un 302, il applique automatiquement la redirection. Dans ce cas, vous verriez l'en-tête dans firebug parce que le navigateur l'a reçu, mais vous ne le verriez pas dans ajax, car le navigateur ne l'a pas transmis. C'est pourquoi les gestionnaires de succès et d'erreur ne sont jamais appelés. Seul le gestionnaire complet est appelé.

http://www.checkupdown.com/status/E302.html

The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser

Voici quelques messages de stackoverflow sur le sujet. Certains articles décrivent des astuces pour contourner ce problème.

Comment gérer une demande de redirection après un appel jQuery Ajax

Capture 302 trouvée en JavaScript

redirection HTTP: 301 (permanent) vs. 302 (temporaire)

17
DRaehal

L'objet XMLHttpRequest sous-jacent utilisé par jQuery suivra toujours les redirections en mode silencieux plutôt que de renvoyer un code d'état 302. Par conséquent, vous ne pouvez pas utiliser la fonctionnalité de demande AJAX de jQuery pour obtenir l'URL renvoyée. Au lieu de cela, vous devez placer toutes les données dans un formulaire et le soumettre avec l'attribut target défini sur la valeur de l'attribut name de l'iframe:

$('#myIframe').attr('name', 'myIframe');

var form = $('<form method="POST" action="url.do"></form>').attr('target', 'myIframe');
$('<input type="hidden" />').attr({name: 'search', value: 'test'}).appendTo(form);

form.appendTo(document.body);
form.submit();

La page url.do du serveur sera chargée dans l'iframe, mais lorsque son état 302 arrivera, l'iframe sera redirigé vers la destination finale.

9
PleaseStand

essaye ça:

type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
    var headers = XMLHttpRequest.getAllResponseHeaders();
}
8
Corey Ballou

+1 à PleaseStand et voici mon autre hack:

après avoir recherché et constaté que la "demande ajax" ne pouvait pas obtenir les en-têtes de réponse de l'objet XHR, j'ai abandonné. et utilisez iframe à la place.

1. <iframe style="display:none"></iframe>
2. $("iframe").attr("src", "http://the_url_you_want_to_access")
//this is my aim!!!
3. $("iframe").contents().find('#someID').html()  
1

MISE À JOUR 2018 POUR JQUERY À PARTIR DE 3 À PLUS TARD

Je sais que c'est une vieille question mais aucune des solutions ci-dessus n'a fonctionné pour moi. Voici la solution qui a fonctionné:

//I only created this function as I am making many ajax calls with different urls and appending the result to different divs
function makeAjaxCall(requestType, urlTo, resultAreaId){
        var jqxhr = $.ajax({
            type: requestType,
            url: urlTo
        });
        //this section is executed when the server responds with no error 
        jqxhr.done(function(){

        });
        //this section is executed when the server responds with error
        jqxhr.fail(function(){

        })
        //this section is always executed
        jqxhr.always(function(){
            console.log("getting header " + jqxhr.getResponseHeader('testHeader'));
        });
    }
1
sticky_elbows