Nagłówek odpowiedzi jQuery i AJAX

163

Otrzymałem więc wywołanie jQuery AJAX, a odpowiedź pochodzi z serwera w postaci przekierowania 302. Chciałbym wziąć to przekierowanie i załadować je w ramce iframe, ale kiedy próbuję wyświetlić informacje nagłówka z alertem javascript, pojawia się wartość null, mimo że firebug widzi to poprawnie.

Oto kod, jeśli to pomoże:

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

Naprawdę nie mam dostępu do rzeczy po stronie serwera, aby przenieść adres URL do treści odpowiedzi, co, jak wiem, byłoby najłatwiejszym rozwiązaniem, więc każda pomoc przy parsowaniu nagłówka byłaby fantastyczna.

Shane
źródło
3
jeśli odwiedzasz to pytanie w 2017 roku lub później, nie trać czasu na większość istniejących odpowiedzi. Jeśli twój problem jest taki sam jak w przypadku OP, masz dwie możliwości: 1) skonfiguruj serwer proxy, który będzie postpierwotny serwer i wyodrębniał dane docelowe, a frontendowy JS zażąda tego serwera proxy dla danych docelowych. Lub 2) zmień kod serwera, aby zezwolić na CORS.
kmonsoor

Odpowiedzi:

186

Rozwiązanie cballou będzie działać, jeśli używasz starej wersji jquery. W nowszych wersjach możesz też spróbować:

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

Zgodnie z dokumentacją obiekt XMLHttpRequest jest dostępny od jQuery 1.4.

Rovsen
źródło
5
Od jQuery> = 1.5 powinien on nazywać się jqXHR , co jest nadzbiorem obiektu XHR.
Johan
136

Jeśli jest to żądanie CORS , możesz zobaczyć wszystkie nagłówki w narzędziach do debugowania (takich jak Chrome-> Inspect Element-> Network), ale obiekt xHR pobierze nagłówek (via xhr.getResponseHeader('Header')) tylko wtedy, gdy taki nagłówek jest prostym nagłówkiem odpowiedzi :

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

Jeśli nie ma go w tym zestawie, musi być obecny w nagłówku Access-Control-Expose-Headers zwróconym przez serwer.

O omawianym przypadku, jeśli jest to żądanie CORS, można będzie pobrać Locationnagłówek za pośrednictwem XMLHttpRequestobiektu tylko wtedy i tylko wtedy, gdy nagłówek poniżej również jest obecny:

Access-Control-Expose-Headers: Location

Jeśli nie jest to żądanie CORS, nie XMLHttpRequestbędzie problemu z jego odzyskaniem.

acdcjunior
źródło
3
@acdcjunior dziękuję, również mi pomogło, po tym, jak zainwestowałem trochę czasu w ustalenie, dlaczego nie było odpowiedzi w nagłówku
daniyel
33
 var geturl;
  geturl = $.ajax({
    type: "GET",
    url: 'http://....',
    success: function () {
      alert("done!"+ geturl.getAllResponseHeaders());
    }
  });
keithics
źródło
1
nie działa dla mnie. może kieruję żądanie do innej witryny? (żądanie między witrynami przy użyciu ajax)
Siwei Shen 申思维
9
Dla ludzi, którzy nie mogliby tego mieć, tak jak ja. Dzieje się tak prawdopodobnie dlatego, że wykonujesz dostęp między domenami, którego jquery nie używa XHR. api.jquery.com/jQuery.get
h - n
Wokowany jak urok .. +1
ErShakirAnsari
18

Niefortunna prawda o AJAX i przekierowaniu 302 jest taka, że ​​nie możesz pobrać nagłówków ze zwrotu, ponieważ przeglądarka nigdy nie przekazuje ich do XHR. Kiedy przeglądarka widzi 302, automatycznie stosuje przekierowanie. W takim przypadku zobaczysz nagłówek w firebug, ponieważ przeglądarka go dostała, ale nie zobaczysz go w Ajax, ponieważ przeglądarka go nie przekazała. Dlatego nigdy nie są wywoływane programy obsługujące powodzenie i błędy. Wywoływana jest tylko pełna obsługa.

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

Oto kilka postów na ten temat. Niektóre posty opisują sposoby na obejście tego problemu.

Jak zarządzać żądaniem przekierowania po wywołaniu jQuery Ajax

Łapanie 302 FOUND w JavaScript

Przekierowanie HTTP: 301 (stałe) i 302 (tymczasowe)

DRaehal
źródło
10

Bazowy obiekt XMLHttpRequest używany przez jQuery zawsze będzie po cichu podążał za przekierowaniami, zamiast zwracać kod stanu 302. W związku z tym nie można użyć funkcji żądania AJAX jQuery do uzyskania zwróconego adresu URL. Zamiast tego musisz umieścić wszystkie dane w formularzu i przesłać formularz z targetatrybutem ustawionym na wartość nameatrybutu elementu 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();

Strona serwera url.dozostanie załadowana do elementu iframe, ale gdy nadejdzie jej stan 302, element iframe zostanie przekierowany do miejsca docelowego.

Proszę wstać
źródło
9

Spróbuj tego:

type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
    var headers = XMLHttpRequest.getAllResponseHeaders();
}
Corey Ballou
źródło
Hmm. Dziękuję bardzo za odpowiedź, ale wciąż zwraca wartość null. Jakieś inne pomysły?
Shane
być może używasz starej wersji jquery.
rovsen
6

UPDATE 2018 DLA JQUERY 3 I PÓŹNIEJ

Wiem, że to stare pytanie, ale żadne z powyższych rozwiązań nie zadziałało. Oto rozwiązanie, które zadziałało:

//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
źródło
2

+1 do PleaseStand, a oto mój inny hack:

po wyszukaniu i stwierdzeniu, że „cross ajax request” nie mógł uzyskać nagłówków odpowiedzi z obiektu XHR, poddałem się. i zamiast tego użyj elementu 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 申思维
źródło