Acceso a los encabezados HTTP de la página web en JavaScript


406

¿Cómo accedo a los encabezados de respuesta HTTP de una página a través de JavaScript?

Relacionado con esta pregunta , que se modificó para preguntar sobre el acceso a dos encabezados HTTP específicos.

Relacionado:
¿Cómo accedo a los campos de encabezado de solicitud HTTP a través de JavaScript?


@ user2284570 - No lo es. Esta pregunta se trata de encabezados de respuesta , no de encabezados de solicitud .
Quentin

Respuestas:


365

No es posible leer los encabezados actuales. Puede realizar otra solicitud a la misma URL y leer sus encabezados, pero no hay garantía de que los encabezados sean exactamente iguales a los actuales.


Use el siguiente código JavaScript para obtener todos los encabezados HTTP realizando una getsolicitud:

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);

58
Saeed, tal vez no sea lo mejor para el autor de la pregunta ... Supongo que es porque no accede a los encabezados de los recursos cargados, sino que hace una nueva solicitud ... obviamente, él sabe cuál es la mejor respuesta, y lo hizo él mismo
mykhal

18
Dependiendo de qué encabezado esté buscando, es posible que desee usar el verbo 'HEAD'.
scottrudy

17
Hacer una nueva solicitud solo funcionará si se garantiza que los valores de respuesta que necesita sean idénticos de una solicitud a la siguiente. Dependerá de su aplicación, por lo que su kilometraje con un enfoque como este variará.
keparo

66
Este truco podría funcionar en algunos escenarios, pero no funcionará en absoluto si la página que contiene el script se generó en respuesta a una solicitud POST, y no ayuda si está tratando de determinar si el servidor encontró un error (HTTP 5XX) mientras procesa la solicitud original.
claymation

99
Esta respuesta es terriblemente incorrecta. La respuesta correcta es "no es posible". O para responder a esta respuesta: "No es posible, pero aquí hay un truco para intentar simularlo que puede o no funcionar para ti".
Jan

301

Desafortunadamente, no hay una API que le proporcione los encabezados de respuesta HTTP para su solicitud de página inicial. Esa fue la pregunta original publicada aquí. También se ha preguntado repetidamente porque a algunas personas les gustaría obtener los encabezados de respuesta reales de la solicitud de página original sin emitir otro.


Para solicitudes AJAX:

Si se realiza una solicitud HTTP a través de AJAX, es posible obtener los encabezados de respuesta con el getAllResponseHeaders()método. Es parte de la API XMLHttpRequest. Para ver cómo se puede aplicar esto, consulte la fetchSimilarHeaders()función a continuación. Tenga en cuenta que esta es una solución al problema que no será confiable para algunas aplicaciones.

myXMLHttpRequest.getAllResponseHeaders();

Esto no le dará información sobre los encabezados de respuesta HTTP de la solicitud de página original, pero podría usarse para hacer conjeturas informadas sobre cuáles eran esos encabezados. Más sobre eso se describe a continuación.


Obtención de valores de encabezado de la solicitud de página inicial:

Esta pregunta se hizo por primera vez hace varios años, preguntando específicamente cómo llegar a los encabezados de respuesta HTTP originales para la página actual (es decir, la misma página dentro de la cual se estaba ejecutando JavaScript). Esta es una pregunta bastante diferente que simplemente obtener los encabezados de respuesta para cualquier solicitud HTTP. Para la solicitud de página inicial, los encabezados no están disponibles para javascript. Si los valores de encabezado que necesita serán confiables y suficientemente consistentes si solicita la misma página nuevamente a través de AJAX, dependerá de su aplicación particular.

Las siguientes son algunas sugerencias para solucionar ese problema.


1. Solicitudes de recursos que son en gran medida estáticos

Si la respuesta es en gran medida estática y no se espera que los encabezados cambien mucho entre solicitudes, puede hacer una solicitud AJAX para la misma página en la que se encuentra actualmente y asumir que son los mismos valores que formaron parte de la página. Respuesta HTTP Esto podría permitirle acceder a los encabezados que necesita utilizando la agradable API XMLHttpRequest descrita anteriormente.

function fetchSimilarHeaders (callback) {
    var request = new XMLHttpRequest();
    request.onreadystatechange = function () {
        if (request.readyState === XMLHttpRequest.DONE) {
            //
            // The following headers may often be similar
            // to those of the original page request...
            //
            if (callback && typeof callback === 'function') {
                callback(request.getAllResponseHeaders());
            }
        }
    };

    //
    // Re-request the same page (document.location)
    // We hope to get the same or similar response headers to those which 
    // came with the current page, but we have no guarantee.
    // Since we are only after the headers, a HEAD request may be sufficient.
    //
    request.open('HEAD', document.location, true);
    request.send(null);
}

Este enfoque será problemático si realmente tiene que confiar en que los valores sean consistentes entre las solicitudes, ya que no puede garantizar completamente que sean los mismos. Dependerá de su aplicación específica y de si sabe que el valor que necesita es algo que no cambiará de una solicitud a la siguiente.


2. Hacer inferencias

Hay algunas propiedades de la lista de materiales (modelo de objetos del navegador) que el navegador determina al observar los encabezados. Algunas de estas propiedades reflejan los encabezados HTTP directamente (por ejemplo, navigator.userAgentse establece en el valor del User-Agentcampo del encabezado HTTP ). Al rastrear las propiedades disponibles, es posible que pueda encontrar lo que necesita o algunas pistas para indicar qué contenía la respuesta HTTP.


3. Guardarlos

Si controla el lado del servidor, puede acceder a cualquier encabezado que desee mientras construye la respuesta completa. Los valores se pueden pasar al cliente con la página, escondidos en algún marcado o tal vez en una estructura JSON en línea. Si desea tener todos los encabezados de solicitud HTTP disponibles para su javascript, puede iterar a través de ellos en el servidor y enviarlos de regreso como valores ocultos en el marcado. Probablemente no sea ideal enviar valores de encabezado de esta manera, pero ciertamente podría hacerlo por el valor específico que necesita. Podría decirse que esta solución también es ineficiente, pero que haría el trabajo si la necesitara.


2
Cómo Google lo detecta como lo expliqué aquí: stackoverflow.com/questions/7191242/…
kamaci

Actualización de RE: las solicitudes de ajax también fueron una parte estándar del desarrollo web en 2008 -_-
BlueRaja - Danny Pflughoeft

55
BOM significa "Modelo de objetos del navegador", para aquellos que se preguntan. Consulte stackoverflow.com/questions/2213594/… para obtener más información.
Myrne Stol

1
3) también podría guardarlos en el encabezado de la cookie http. Entonces no necesitaría cambiar el marcado del documento.
skibulk

Hay una manera simple de acceder a los elementos del encabezado de respuesta, como el elemento de enlace: use el ejemplo del documento aquí: gist.github.com/FunThomas424242/…
FunThomas424242


24

Una solución con Service Workers

Los trabajadores del servicio pueden acceder a la información de la red, que incluye encabezados. Lo bueno es que funciona en cualquier tipo de solicitud, no solo en XMLHttpRequest.

Cómo funciona:

  1. Agregue un trabajador de servicio en su sitio web.
  2. Mire cada solicitud que se envía.
  3. Haga que el trabajador del servicio fetchsolicite la respondWithfunción.
  4. Cuando llegue la respuesta, lea los encabezados.
  5. Envíe los encabezados del trabajador de servicio a la página con la postMessagefunción.

Ejemplo de trabajo:

Los trabajadores de servicio son un poco complicados de entender, así que he construido una pequeña biblioteca que hace todo esto. Está disponible en github: https://github.com/gmetais/sw-get-headers .

Limitaciones:

  • el sitio web debe estar en HTTPS
  • el navegador debe ser compatible con la API de Service Workers
  • las políticas del mismo dominio / dominio cruzado están en acción, al igual que en XMLHttpRequest

12

Para aquellos que buscan una forma de analizar todos los encabezados HTTP en un objeto al que se puede acceder como un diccionario headers["content-type"], he creado una función parseHttpHeaders:

function parseHttpHeaders(httpHeaders) {
    return httpHeaders.split("\n")
     .map(x=>x.split(/: */,2))
     .filter(x=>x[0])
     .reduce((ac, x)=>{ac[x[0]] = x[1];return ac;}, {});
}

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = parseHttpHeaders(req.getAllResponseHeaders());
// Now we can do:  headers["content-type"]

10

Otra forma de enviar información de encabezado a JavaScript sería a través de cookies. El servidor puede extraer los datos que necesita de los encabezados de solicitud y enviarlos nuevamente dentro de un Set-Cookieencabezado de respuesta, y las cookies se pueden leer en JavaScript. Sin embargo, como dice keparo, es mejor hacer esto solo para uno o dos encabezados, en lugar de hacerlo para todos.


1
Este enfoque aún requiere que controle el servidor para su JS. No importa cómo comunique esa información, su código se ha convertido en caché de repente. ¿Por qué no simplemente hacer una API para esa solicitud específica para evitar corromper la solicitud del activo original?
MST del

5

Si estamos hablando de Solicitud de cabeceras, puede crear sus propias cabeceras cuando se hace XmlHttpRequests.

var request = new XMLHttpRequest();
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.open("GET", path, true);
request.send(null);

no podrá modificar el encabezado de la solicitud en mozilla por razones de seguridad. mxr.mozilla.org/mozilla1.8.0/source/extensions/xmlextras/base/…
user121196

1
Debe llamar a open () antes de usar el método setRequestHeader (). developer.mozilla.org/en/…
XP1

1
El acceso, en la pregunta original, se trata de obtener encabezados, no de configurar encabezados.
Timo Tijhof

4

No puede acceder a los encabezados http, pero parte de la información provista en ellos está disponible en el DOM. Por ejemplo, si desea ver el http referer (sic), use document.referrer. Puede haber otros como este para otros encabezados http. Intenta buscar en Google lo específico que deseas, como "http referer javascript".

Sé que esto debería ser obvio, pero seguí buscando cosas como "http encabezados javascript" cuando todo lo que realmente quería era el árbitro, y no obtuve ningún resultado útil. No sé cómo no me di cuenta de que podía hacer una consulta más específica.


4

Como muchas personas, he estado cavando la red sin una respuesta real :(

Sin embargo, he descubierto un bypass que podría ayudar a otros. En mi caso, controlo completamente mi servidor web. De hecho, es parte de mi aplicación (ver referencia final). Es fácil para mí agregar un script a mi respuesta http. Modifiqué mi servidor httpd para inyectar un pequeño script en cada página html. Solo empujo una línea adicional 'js script' justo después de la construcción de mi encabezado, que establece una variable existente de mi documento dentro de mi navegador [elijo la ubicación], pero cualquier otra opción es posible. Si bien mi servidor está escrito en nodejs, no tengo dudas de que se puede usar la misma técnica desde PHP u otros.

  case ".html":
    response.setHeader("Content-Type", "text/html");
    response.write ("<script>location['GPSD_HTTP_AJAX']=true</script>")
    // process the real contend of my page

Ahora todas las páginas html cargadas desde mi servidor, tienen este script ejecutado por el navegador en la recepción. Entonces puedo verificar fácilmente desde JavaScript si la variable existe o no. En mi caso de uso, necesito saber si debo usar el perfil JSON o JSON-P para evitar el problema CORS, pero la misma técnica se puede usar para otros fines [es decir: elegir entre el servidor de desarrollo / producción, obtener del servidor un REST / API llave, etc ....]

En el navegador solo necesita verificar la variable directamente desde JavaScript como en mi ejemplo, donde lo uso para seleccionar mi perfil Json / JQuery

 // Select direct Ajax/Json profile if using GpsdTracking/HttpAjax server otherwise use JsonP
  var corsbypass = true;  
  if (location['GPSD_HTTP_AJAX']) corsbypass = false;

  if (corsbypass) { // Json & html served from two different web servers
    var gpsdApi = "http://localhost:4080/geojson.rest?jsoncallback=?";
  } else { // Json & html served from same web server [no ?jsoncallback=]
    var gpsdApi = "geojson.rest?";
  }
  var gpsdRqt = 
      {key   :123456789 // user authentication key
      ,cmd   :'list'    // rest command
      ,group :'all'     // group to retreive
      ,round : true     // ask server to round numbers
   };
   $.getJSON(gpsdApi,gpsdRqt, DevListCB);

Para quien quiera revisar mi código: https://www.npmjs.org/package/gpsdtracking


3

Usando mootools, puede usar this.xhr.getAllResponseHeaders ()


3

Acabo de probar, y esto funciona para mí usando Chrome Versión 28.0.1500.95.

Necesitaba descargar un archivo y leer el nombre del archivo. El nombre del archivo está en el encabezado, así que hice lo siguiente:

var xhr = new XMLHttpRequest(); 
xhr.open('POST', url, true); 
xhr.responseType = "blob";
xhr.onreadystatechange = function () { 
    if (xhr.readyState == 4) {
        success(xhr.response); // the function to proccess the response

        console.log("++++++ reading headers ++++++++");
        var headers = xhr.getAllResponseHeaders();
        console.log(headers);
        console.log("++++++ reading headers end ++++++++");

    }
};

Salida:

Date: Fri, 16 Aug 2013 16:21:33 GMT
Content-Disposition: attachment;filename=testFileName.doc
Content-Length: 20
Server: Apache-Coyote/1.1
Content-Type: application/octet-stream

2

Este es mi script para obtener todos los encabezados de respuesta:

var url = "< URL >";

var req = new XMLHttpRequest();
req.open('HEAD', url, false);
req.send(null);
var headers = req.getAllResponseHeaders();

//Show alert with response headers.
alert(headers);

Teniendo como resultado los encabezados de respuesta.

ingrese la descripción de la imagen aquí

Esta es una prueba de comparación usando Hurl.it:

ingrese la descripción de la imagen aquí


2

Para obtener los encabezados como un objeto que es más útil (mejora de la respuesta de Raja ):

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
headers = headers.split(/\n|\r|\r\n/g).reduce(function(a, b) {
    if (b.length) {
        var [ key, value ] = b.split(': ');
        a[key] = value;
    }
    return a;
}, {});
console.log(headers);

2

El enlace de Allain Lalonde me alegró el día. Solo agrego un código html de trabajo simple aquí.
Funciona con cualquier navegador razonable desde hace años más IE9 + y Presto-Opera 12.

<!DOCTYPE html>
<title>(XHR) Show all response headers</title>

<h1>All Response Headers with XHR</h1>
<script>
 var X= new XMLHttpRequest();
 X.open("HEAD", location);
 X.send();
 X.onload= function() { 
   document.body.appendChild(document.createElement("pre")).textContent= X.getAllResponseHeaders();
 }
</script>

Nota: Obtiene encabezados de una segunda solicitud, el resultado puede diferir de la solicitud inicial.


Otra forma
es la fetch()API más moderna
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
Por caniuse.com es compatible con Firefox 40, Chrome 42, Edge 14, Safari 11
Ejemplo de trabajo código:

<!DOCTYPE html>
<title>fetch() all Response Headers</title>

<h1>All Response Headers with fetch()</h1>
<script>
 var x= "";
 if(window.fetch)
    fetch(location, {method:'HEAD'})
    .then(function(r) {
       r.headers.forEach(
          function(Value, Header) { x= x + Header + "\n" + Value + "\n\n"; }
       );
    })
    .then(function() {
       document.body.appendChild(document.createElement("pre")).textContent= x;
    });
 else
   document.write("This does not work in your browser - no support for fetch API");
</script>

0

Esta es una vieja pregunta. No está seguro de que el apoyo se hizo más amplia, pero getAllResponseHeaders()y getResponseHeader()parece ser ahora bastante estándar: http://www.w3schools.com/xml/dom_http.asp


50
getAllResponseHeaders () y getResponseHeader () son métodos del objeto XMLHttpRequest. Es decir, para solicitudes ajax. No puede usar esos métodos para ver los encabezados de la página inicial, que es lo que creo que realmente estaba haciendo la pregunta original.
asgeo1

-1

Como ya se mencionó, si controla el lado del servidor, entonces debería ser posible enviar los encabezados de solicitud iniciales al cliente en la respuesta inicial.

En Express, por ejemplo, lo siguiente funciona:

app.get('/somepage', (req, res) => { res.render('somepage.hbs', {headers: req.headers}); }) Los encabezados están disponibles dentro de la plantilla, por lo que podrían ocultarse visualmente pero incluirse en el marcado y leerse en el JavaScript del lado del cliente.


La pregunta es acerca de los encabezados de respuesta , no de los encabezados de solicitud.
Quentin

-1

Creo que la pregunta fue incorrecta, si desea tomar el encabezado Solicitud de JQuery / JavaScript, la respuesta es simplemente No. Las otras soluciones son crear una página aspx o una página jsp, entonces podemos acceder fácilmente al encabezado de solicitud. Tome toda la solicitud en la página aspx y colóquela en una sesión / cookies, luego puede acceder a las cookies en la página JavaScript.


1
La pregunta es acerca de leer los encabezados de respuesta . Menciona los encabezados de solicitud solo en el contexto de la pregunta posiblemente relacionada.
Quentin
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.