jQuery e cabeçalho de resposta AJAX

163

Então, eu recebi essa chamada do jQuery AJAX e a resposta vem do servidor na forma de um redirecionamento 302. Gostaria de pegar esse redirecionamento e carregá-lo em um iframe, mas quando tento exibir as informações do cabeçalho com um alerta javascript, ele aparece nulo, mesmo que o firebug as veja corretamente.

Aqui está o código, se ajudar:

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

Eu realmente não tenho acesso ao material do lado do servidor para mover o URL para o corpo da resposta, que eu sei que seria a solução mais fácil, portanto, qualquer ajuda com a análise do cabeçalho seria fantástica.

Shane
fonte
3
se você estiver visitando esta pergunta em 2017 ou mais tarde, não perca tempo com a maioria das respostas existentes. Se o seu problema for o mesmo do OP, você terá duas opções: 1) configurar um servidor proxy que postextrairá o servidor original e extrairá os dados de destino e o JS de front-end solicitará esse servidor proxy para os dados de destino. Ou 2) altere o código do servidor para permitir o CORS.
kmonsoor 13/02/2017

Respostas:

186

A solução do cballou funcionará se você estiver usando uma versão antiga do jquery. Nas versões mais recentes, você também pode tentar:

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

De acordo com a documentação, o objeto XMLHttpRequest está disponível a partir do jQuery 1.4.

rovsen
fonte
5
A partir do jQuery> = 1.5, ele deve ser chamado jqXHR , que é um superconjunto de um objeto XHR.
Johan
136

Se for uma solicitação CORS , você poderá ver todos os cabeçalhos nas ferramentas de depuração (como Chrome-> Inspect Element-> Network), mas o objeto xHR recuperará apenas o cabeçalho (via xhr.getResponseHeader('Header')) se esse cabeçalho for um cabeçalho de resposta simples :

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

Se não estiver neste conjunto, deverá estar presente no cabeçalho Access-Control-Expose-Headers retornado pelo servidor.

Sobre o caso em questão, se for uma solicitação CORS, só será possível recuperar o Locationcabeçalho através do XMLHttpRequestobjeto se, e somente se, o cabeçalho abaixo também estiver presente:

Access-Control-Expose-Headers: Location

Se não for uma solicitação do CORS, XMLHttpRequestnão haverá problemas para recuperá-la.

acdcjunior
fonte
3
@acdcjunior obrigado isso me ajudou também, depois de ter investido algum tempo para descobrir por que não havia saída em resposta cabeçalho
Daniyel
33
 var geturl;
  geturl = $.ajax({
    type: "GET",
    url: 'http://....',
    success: function () {
      alert("done!"+ geturl.getAllResponseHeaders());
    }
  });
keithics
fonte
1
Nao funciona para mim. talvez eu esteja fazendo a solicitação para outro site? (solicitação de site cruzado usando ajax)
Siwei Shen 申思维 10/10
9
Para pessoas que não poderiam ter isso funcionado como eu. Provavelmente é porque você está fazendo um acesso entre domínios que o jquery não usa XHR. api.jquery.com/jQuery.get
h - n
Woked like a charm .. +1
ErShakirAnsari 28/07/19
18

A infeliz verdade sobre o AJAX e o redirecionamento 302 é que você não pode obter os cabeçalhos do retorno porque o navegador nunca os fornece ao XHR. Quando um navegador vê um 302, ele aplica automaticamente o redirecionamento. Nesse caso, você veria o cabeçalho no firebug porque o navegador o obteve, mas não no ajax, porque o navegador não o passou. É por isso que o sucesso e os manipuladores de erros nunca são chamados. Somente o manipulador completo é chamado.

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

Aqui estão algumas postagens de stackoverflow sobre o assunto. Algumas das postagens descrevem hacks para contornar esse problema.

Como gerenciar uma solicitação de redirecionamento após uma chamada do jQuery Ajax

Pegando 302 FOUND em JavaScript

Redirecionamento HTTP: 301 (permanente) vs. 302 (temporário)

DRaehal
fonte
10

O objeto XMLHttpRequest subjacente usado pelo jQuery sempre segue silenciosamente os redirecionamentos, em vez de retornar um código de status 302. Portanto, você não pode usar a funcionalidade de solicitação AJAX do jQuery para obter a URL retornada. Em vez disso, você precisa colocar todos os dados em um formulário e enviá-lo com o targetatributo definido para o valor do nameatributo do 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();

A url.dopágina do servidor será carregada no iframe, mas quando seu status 302 chegar, o iframe será redirecionado para o destino final.

PleaseStand
fonte
9

tente isto:

type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
    var headers = XMLHttpRequest.getAllResponseHeaders();
}
Corey Ballou
fonte
Hmm. Muito obrigado pela resposta, mas isso ainda está retornando nulo. Alguma outra ideia?
2111 Shane
talvez você esteja usando uma versão antiga do jquery.
Rovsen
6

ATUALIZAÇÃO 2018 PARA O JQUERY 3 E MAIS TARDE

Sei que essa é uma pergunta antiga, mas nenhuma das soluções acima funcionou para mim. Aqui está a solução que funcionou:

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

+1 para PleaseStand e aqui está meu outro hack:

depois de pesquisar e constatar que a "solicitação cruzada de ajax" não pôde obter os cabeçalhos de resposta do objeto XHR, desisti. e use 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 申思维
fonte