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

163

J'ai donc cet appel jQuery AJAX, et la réponse vient du serveur sous la forme d'une redirection 302. Je voudrais 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, elle est nulle, même si Firebug la voit correctement.

Voici le code, si cela peut vous aider:

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

Je n'ai pas vraiment accès aux éléments côté serveur pour déplacer l'URL vers le corps de la réponse, ce qui, je le sais, serait la solution la plus simple, donc toute aide pour l'analyse de l'en-tête serait fantastique.

Shane
la source
3
si vous consultez cette question en 2017 ou après, ne perdez pas de temps avec la plupart des réponses existantes. Si votre problème est le même que OP, vous avez deux options: 1) configurer un serveur proxy qui sera postle serveur d'origine et extraira les données cibles et le front-end JS demandera ce serveur proxy pour les données cibles. Ou, 2) changez le code du serveur pour autoriser CORS.
kmonsoor

Réponses:

186

La solution de cballou fonctionnera si vous utilisez une ancienne version de jquery. Dans les versions plus récentes, 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 la documentation, l'objet XMLHttpRequest est disponible à partir de jQuery 1.4.

Rovsen
la source
5
À partir de jQuery> = 1.5, il devrait être appelé jqXHR , qui est un sur-ensemble d'un objet XHR.
Johan
136

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

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

S'il ne figure pas dans 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 requête CORS, on ne pourra récupérer l'en- Locationtête à travers l' XMLHttpRequestobjet que 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 requête CORS, vous XMLHttpRequestn'aurez aucun problème à le récupérer.

acdcjunior
la source
3
@acdcjunior merci, cela m'a aidé aussi, après avoir investi un certain temps pour découvrir pourquoi il n'y avait pas de sortie dans la réponse d'en-tête
daniyel
33
 var geturl;
  geturl = $.ajax({
    type: "GET",
    url: 'http://....',
    success: function () {
      alert("done!"+ geturl.getAllResponseHeaders());
    }
  });
keithics
la source
1
ne fonctionne pas pour moi. peut-être que je fais la demande sur un autre site? (requête
intersite
9
Pour les gens qui ne pouvaient pas faire fonctionner comme moi. C'est probablement parce que vous effectuez un accès interdomaine dont jquery n'utilise pas XHR. api.jquery.com/jQuery.get
h - n
Réveillé comme un charme .. +1
ErShakirAnsari
18

La triste vérité sur AJAX et la redirection 302 est que vous ne pouvez pas obtenir les en-têtes du retour car le navigateur ne les donne jamais au 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 obtenu, mais vous ne le verriez pas en ajax, car le navigateur ne l'a pas transmis. C'est pourquoi le succès et les gestionnaires d'erreurs 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 articles de stackoverflow sur le sujet. Certains articles décrivent des hacks pour contourner ce problème.

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

Catching 302 TROUVÉ en JavaScript

Redirection HTTP: 301 (permanent) vs 302 (temporaire)

DRaehal
la source
10

L'objet XMLHttpRequest sous-jacent utilisé par jQuery suivra toujours silencieusement les redirections plutôt que de renvoyer un code d'état 302. Par conséquent, vous ne pouvez pas utiliser la fonctionnalité de requête AJAX de jQuery pour obtenir l'URL renvoyée. Au lieu de cela, vous devez mettre toutes les données dans un formulaire et soumettre le formulaire avec l' targetattribut défini sur la valeur de l' nameattribut 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 url.dopage du serveur sera chargée dans l'iframe, mais lorsque son statut 302 arrivera, l'iframe sera redirigé vers la destination finale.

Veuillez vous lever
la source
9

essaye ça:

type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
    var headers = XMLHttpRequest.getAllResponseHeaders();
}
Corey Ballou
la source
Hmm. Merci beaucoup pour la réponse, mais cela renvoie toujours null. D'autres idées?
Shane
peut-être que vous utilisez une ancienne version de jquery.
rovsen
6

MISE À JOUR 2018 POUR JQUERY 3 ET 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'));
        });
    }
sticky_elbows
la source
2

+1 à PleaseStand et voici mon autre hack:

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

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()  
Siwei Shen 申思维
la source