Encabezado de respuesta jQuery y AJAX

163

Así que tengo esta llamada jQuery AJAX, y la respuesta proviene del servidor en forma de una redirección 302. Me gustaría tomar este redireccionamiento y cargarlo en un iframe, pero cuando intento ver la información del encabezado con una alerta de JavaScript, aparece nulo, aunque firebug lo ve correctamente.

Aquí está el código, si te ayudará:

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

Realmente no tengo acceso a las cosas del lado del servidor para mover la URL al cuerpo de respuesta, lo cual sé que sería la solución más fácil, por lo que cualquier ayuda con el análisis del encabezado sería fantástica.

Shane
fuente
3
Si está visitando esta pregunta en 2017 o más tarde, no pierda el tiempo con la mayoría de las respuestas existentes. Si su problema es el mismo que OP, tiene dos opciones: 1) configurar un servidor proxy que será postel servidor original y extraerá los datos de destino y JS front-end solicitará este servidor proxy para los datos de destino. O 2) cambie el código del servidor para permitir CORS.
kmonsoor

Respuestas:

186

La solución de cballou funcionará si está utilizando una versión anterior de jquery. En versiones más recientes también puedes probar:

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

Según los documentos, el objeto XMLHttpRequest está disponible a partir de jQuery 1.4.

Rovsen
fuente
55
A partir de jQuery> = 1.5, debería llamarse jqXHR , que es un superconjunto de un objeto XHR.
Johan
136

Si se trata de una solicitud CORS , es posible que vea todos los encabezados en las herramientas de depuración (como Chrome-> Inspect Element-> Network), pero el objeto xHR solo recuperará el encabezado (via xhr.getResponseHeader('Header')) si dicho encabezado es un encabezado de respuesta simple :

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

Si no está en este conjunto, debe estar presente en el encabezado Access-Control-Expose-Headers devuelto por el servidor.

Sobre el caso en cuestión, si se trata de una solicitud CORS, uno solo podrá recuperar el Locationencabezado a través del XMLHttpRequestobjeto si, y solo si, el encabezado a continuación también está presente:

Access-Control-Expose-Headers: Location

Si no es una solicitud CORS, XMLHttpRequestno tendrá problemas para recuperarla.

acdcjunior
fuente
3
@acdcjunior gracias, también me ayudó, después de haber invertido algo de tiempo en descubrir por qué no hubo salida en la respuesta del encabezado
daniyel
33
 var geturl;
  geturl = $.ajax({
    type: "GET",
    url: 'http://....',
    success: function () {
      alert("done!"+ geturl.getAllResponseHeaders());
    }
  });
keithics
fuente
1
no funciona para mi tal vez estoy haciendo la solicitud a otro sitio? (solicitud de sitio cruzado usando ajax)
Siwei Shen 申思维
9
Para las personas que no podían hacer que funcionara como yo. Probablemente sea porque está haciendo un acceso de dominio cruzado que jquery no usa XHR. api.jquery.com/jQuery.get
h - n
Woked as a charm .. +1
ErShakirAnsari
18

La desafortunada verdad sobre AJAX y la redirección 302 es que no puede obtener los encabezados del retorno porque el navegador nunca los entrega al XHR. Cuando un navegador ve un 302, aplica automáticamente la redirección. En este caso, vería el encabezado en firebug porque el navegador lo obtuvo, pero no lo vería en ajax, porque el navegador no lo pasó. Esta es la razón por la cual nunca se llama al controlador de éxito y error. Solo se llama al controlador completo.

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

Aquí hay algunas publicaciones de stackoverflow sobre el tema. Algunas de las publicaciones describen hacks para solucionar este problema.

Cómo administrar una solicitud de redireccionamiento después de una llamada jQuery Ajax

Cogiendo 302 ENCONTRADO en JavaScript

Redirección HTTP: 301 (permanente) frente a 302 (temporal)

DRaehal
fuente
10

El objeto XMLHttpRequest subyacente utilizado por jQuery siempre seguirá silenciosamente las redirecciones en lugar de devolver un código de estado 302. Por lo tanto, no puede utilizar la funcionalidad de solicitud AJAX de jQuery para obtener la URL devuelta. En su lugar, debe poner todos los datos en un formulario y enviar el formulario con el targetatributo establecido al valor del nameatributo del 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.dopágina del servidor se cargará en el iframe, pero cuando llegue su estado 302, el iframe se redirigirá al destino final.

Por favor levantese
fuente
9

prueba esto:

type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
    var headers = XMLHttpRequest.getAllResponseHeaders();
}
Corey Ballou
fuente
Hmm Muchas gracias por la respuesta, pero eso sigue siendo nulo. ¿Alguna otra idea?
Shane
tal vez estás usando una versión antigua de jquery.
rovsen
6

ACTUALIZACIÓN 2018 PARA JQUERY 3 Y MÁS TARDE

Sé que esta es una vieja pregunta, pero ninguna de las soluciones anteriores funcionó para mí. Aquí está la solución que funcionó:

//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'));
        });
    }
codos pegajosos
fuente
2

+1 a PleaseStand y aquí está mi otro truco:

Después de buscar y encontrar que la "solicitud de cross ajax" no podía obtener encabezados de respuesta del objeto XHR, me di por vencido. y use iframe en su lugar.

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 申思维
fuente