jQuery- und AJAX-Antwortheader

163

Ich habe also diesen jQuery AJAX-Aufruf und die Antwort kommt vom Server in Form einer 302-Umleitung. Ich möchte diese Umleitung nehmen und in einen Iframe laden, aber wenn ich versuche, die Header-Informationen mit einer Javascript-Warnung anzuzeigen, wird sie als null angezeigt, obwohl Firebug sie korrekt sieht.

Hier ist der Code, wenn es hilft:

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

Ich habe nicht wirklich Zugriff auf die serverseitigen Inhalte, um die URL in den Antworttext zu verschieben. Ich weiß, dass dies die einfachste Lösung ist. Daher wäre jede Hilfe beim Parsen des Headers fantastisch.

Shane
quelle
3
Wenn Sie diese Frage 2017 oder später besuchen, verschwenden Sie bitte keine Zeit mit den meisten vorhandenen Antworten. Wenn Ihr Problem mit OP identisch ist, haben Sie zwei Möglichkeiten: 1) Richten Sie einen Proxyserver ein, der postden ursprünglichen Server verwendet und Zieldaten extrahiert, und Front-End-JS fordert diesen Proxyserver für die Zieldaten an. Oder 2) Ändern Sie den Servercode, um CORS zuzulassen.
kmonsoor

Antworten:

186

Die Lösung von cballou funktioniert, wenn Sie eine alte Version von jquery verwenden. In neueren Versionen können Sie auch versuchen:

  $.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'));
   }
  });

Laut docs ist das XMLHttpRequest-Objekt ab jQuery 1.4 verfügbar.

Rovsen
quelle
5
Ab jQuery> = 1.5 sollte es jqXHR heißen , eine Obermenge eines XHR-Objekts.
Johan
136

Wenn es sich um eine CORS-Anforderung handelt , werden möglicherweise alle Header in Debug-Tools angezeigt (z. B. Chrome-> Inspect Element-> Network). Das xHR-Objekt ruft den Header jedoch nur (via xhr.getResponseHeader('Header')) ab, wenn es sich bei einem solchen Header um einen einfachen Antwortheader handelt :

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

Wenn es nicht in diesem Set enthalten ist, muss es in den Access-Control-Expose-Headern vorhanden sein vom Server zurückgegebenen Headers vorhanden sein.

In Bezug auf den fraglichen Fall kann man, wenn es sich um eine CORS-Anforderung handelt, den LocationHeader XMLHttpRequestnur dann über das Objekt abrufen, wenn und nur wenn auch der folgende Header vorhanden ist:

Access-Control-Expose-Headers: Location

Wenn es sich nicht um eine CORS-Anfrage handelt, XMLHttpRequestkann sie problemlos abgerufen werden.

acdcjunior
quelle
3
@acdcjunior danke, es hat mir auch geholfen, nachdem ich einige Zeit investiert habe, um herauszufinden, warum es keine Ausgabe in der Header-Antwort gab
daniyel
33
 var geturl;
  geturl = $.ajax({
    type: "GET",
    url: 'http://....',
    success: function () {
      alert("done!"+ geturl.getAllResponseHeaders());
    }
  });
Keithics
quelle
1
funktioniert bei mir nicht Vielleicht mache ich die Anfrage an eine andere Seite? (Cross Site Anfrage mit Ajax)
Siwei Shen 申思维
9
Für Leute, die es nicht so haben konnten wie ich. Dies liegt wahrscheinlich daran, dass Sie einen domänenübergreifenden Zugriff durchführen, bei dem jquery XHR nicht verwendet. api.jquery.com/jQuery.get
h - n
Wachte wie ein Zauber auf .. +1
ErShakirAnsari
18

Die unglückliche Wahrheit über AJAX und die 302-Weiterleitung ist, dass Sie die Header nicht aus der Rückgabe abrufen können, da der Browser sie niemals an die XHR weitergibt. Wenn ein Browser einen 302 sieht, wendet er automatisch die Umleitung an. In diesem Fall würden Sie den Header in Firebug sehen, weil der Browser ihn erhalten hat, aber Sie würden ihn nicht in Ajax sehen, weil der Browser ihn nicht bestanden hat. Aus diesem Grund werden die Erfolgs- und Fehlerbehandlungsroutinen nie aufgerufen. Es wird nur der vollständige Handler aufgerufen.

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

Hier sind einige Stackoverflow-Beiträge zu diesem Thema. Einige der Beiträge beschreiben Hacks, um dieses Problem zu umgehen.

So verwalten Sie eine Umleitungsanforderung nach einem jQuery Ajax-Aufruf

Catching 302 FOUND in JavaScript

HTTP-Weiterleitung: 301 (permanent) vs. 302 (temporär)

DRaehal
quelle
10

Das zugrunde liegende XMLHttpRequest-Objekt, das von jQuery verwendet wird, folgt immer stillschweigend Weiterleitungen, anstatt einen 302-Statuscode zurückzugeben. Daher können Sie die AJAX-Anforderungsfunktionalität von jQuery nicht verwenden, um die zurückgegebene URL abzurufen. Stattdessen müssen Sie alle Daten in ein Formular einfügen und das Formular mit dem targetAttribut senden, das auf den Wert des nameAttributs des Iframes festgelegt ist:

$('#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();

Die url.doSeite des Servers wird in den Iframe geladen, aber wenn sein 302-Status eintrifft, wird der Iframe zum endgültigen Ziel umgeleitet.

PleaseStand
quelle
9

Versuche dies:

type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
    var headers = XMLHttpRequest.getAllResponseHeaders();
}
Corey Ballou
quelle
Hmm. Vielen Dank für die Antwort, aber das gibt immer noch null zurück. Irgendwelche anderen Ideen?
Shane
Vielleicht verwenden Sie eine alte Version von jquery.
Rovsen
6

UPDATE 2018 FÜR JQUERY 3 UND SPÄTER

Ich weiß, dass dies eine alte Frage ist, aber keine der oben genannten Lösungen hat für mich funktioniert. Hier ist die Lösung, die funktioniert hat:

//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
quelle
2

+1 zu PleaseStand und hier ist mein anderer Hack:

Nachdem ich gesucht und festgestellt hatte, dass die "Cross-Ajax-Anfrage" keine Antwortheader vom XHR-Objekt erhalten konnte, gab ich auf. und verwenden Sie stattdessen 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 申思维
quelle