web-dev-qa-db-fra.com

Accéder aux en-têtes HTTP de la page Web en JavaScript

Comment accéder aux en-têtes de réponse HTTP d'une page via JavaScript?

Relatif à cette question , qui a été modifié pour demander l’accès à deux en-têtes HTTP spécifiques.

Connexes:
Comment puis-je accéder aux champs d'en-tête de requête HTTP via JavaScript?

383
keparo

Malheureusement, il n'y a pas d'API pour vous donner les en-têtes de réponse HTTP pour votre demande de page initiale. Telle était la question initiale posée ici. Cela a été demandé à maintes reprises , également, car certaines personnes souhaiteraient obtenir les en-têtes de réponse de la demande de page d'origine sans en publier une autre.


Pour AJAX Demandes:

Si une requête HTTP est effectuée sur AJAX, il est possible d'obtenir les en-têtes de réponse avec la méthode getAllResponseHeaders(). Cela fait partie de l'API XMLHttpRequest. Pour voir comment cela peut être appliqué, vérifiez la fonction fetchSimilarHeaders() ci-dessous. Notez qu'il s'agit d'une solution au problème qui ne sera pas fiable pour certaines applications.

myXMLHttpRequest.getAllResponseHeaders();

Cela ne vous donnera pas d'informations sur les en-têtes de réponse HTTP de la demande de page d'origine, mais il pourrait être utilisé pour faire des suppositions éclairées sur le contenu de ces en-têtes. Plus sur ce qui est décrit ensuite.


Obtention des valeurs d’en-tête à partir de la demande de page initiale:

Cette question a été posée pour la première fois il y a plusieurs années, et portait spécifiquement sur la manière d'obtenir les en-têtes de réponse HTTP d'origine pour page actuelle (c'est-à-dire la même page à l'intérieur de laquelle s'exécutait le javascript). C'est une question assez différente de celle d'obtenir simplement les en-têtes de réponse pour toute requête HTTP. Pour la demande de page initiale, les en-têtes ne sont pas facilement disponibles pour javascript. Le fait de savoir si les valeurs d'en-tête dont vous avez besoin sera fiable et suffisamment cohérent si vous redemandez la même page via AJAX dépend de votre application.

Voici quelques suggestions pour résoudre ce problème.


1. Requêtes sur des ressources en grande partie statiques

Si la réponse est en grande partie statique et que les en-têtes ne devraient pas beaucoup changer entre les demandes, vous pouvez faire une demande AJAX pour la même page sur laquelle vous vous trouvez et supposer que ce sont les mêmes valeurs. qui faisaient partie de la réponse HTTP de la page. Cela pourrait vous permettre d'accéder aux en-têtes dont vous avez besoin à l'aide de l'API Nice XMLHttpRequest décrite ci-dessus.

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);
}

Cette approche sera problématique si vous devez vraiment vous fier à la cohérence des valeurs entre les demandes, étant donné que vous ne pouvez pas garantir qu'elles sont identiques. Cela dépendra de votre application spécifique et si vous savez que la valeur dont vous avez besoin est quelque chose qui ne changera pas d'une demande à l'autre.


2. Faire des inférences

Il existe des propriétés de nomenclature (modèle d'objet de navigateur) que le navigateur détermine en consultant les en-têtes. Certaines de ces propriétés reflètent directement les en-têtes HTTP (par exemple, navigator.userAgent est défini sur la valeur du champ d’en-tête HTTP User-Agent). En détectant les propriétés disponibles, vous pourrez peut-être trouver ce dont vous avez besoin ou des indices pour indiquer le contenu de la réponse HTTP.


3. Les cacher

Si vous contrôlez le côté serveur, vous pouvez accéder à n’importe quel en-tête de votre choix lors de la construction de la réponse complète. Les valeurs peuvent être transmises au client avec la page, stockées dans un balisage ou peut-être dans une structure JSON intégrée. Si vous souhaitez que chaque en-tête de requête HTTP soit disponible pour votre javascript, vous pouvez le parcourir via le serveur et le renvoyer sous forme de valeurs masquées dans le balisage. Ce n'est probablement pas idéal d'envoyer les valeurs d'en-tête de cette façon, mais vous pouvez certainement le faire pour la valeur spécifique dont vous avez besoin. Cette solution est également inefficace, mais elle ferait l'affaire si vous en aviez besoin.

290
keparo

Il n'est pas possible de lire les en-têtes actuels. Vous pouvez faire une autre demande à la même URL et lire ses en-têtes, mais rien ne garantit que les en-têtes sont exactement égaux au courant.


Utilisez le code JavaScript suivant pour obtenir tous les en-têtes HTTP en effectuant une requête get:

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

En utilisant XmlHttpRequest, vous pouvez afficher la page actuelle, puis examiner les en-têtes http de la réponse.

Le meilleur des cas est simplement de faire une requête HEAD puis d'examiner les en-têtes.

Pour quelques exemples, consultez http://www.jibbering.com/2002/4/httprequest.html

Juste mes 2 cents.

27
Allain Lalonde

Une solution avec les travailleurs du service

Les agents de service peuvent accéder aux informations du réseau, notamment les en-têtes. La bonne partie est que cela fonctionne sur tout type de requête, pas seulement XMLHttpRequest.

Comment ça fonctionne:

  1. Ajoutez un technicien de service sur votre site Web.
  2. Regardez chaque demande envoyée.
  3. Définissez le service worker fetch la demande avec la fonction respondWith.
  4. Lorsque la réponse arrive, lisez les en-têtes.
  5. Envoyez les en-têtes du technicien de service à la page avec la fonction postMessage.

Exemple de travail:

Les ouvriers du service étant un peu compliqués à comprendre, j'ai donc construit une petite bibliothèque qui fait tout cela. Il est disponible sur github: https://github.com/gmetais/sw-get-headers .

Limites:

  • le site Web doit être activé HTTPS
  • le navigateur doit prendre en charge l'API Service Workers
  • les stratégies de même domaine/inter-domaines sont en action, comme sur XMLHttpRequest
15
Gaël Métais

Pour ceux qui recherchent un moyen d’analyser tous les en-têtes HTTP dans un objet accessible sous forme de dictionnaire headers["content-type"], j’ai créé une fonction 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
Diego

Les cookies constituent un autre moyen d’envoyer des informations d’en-tête à JavaScript. Le serveur peut extraire les données dont il a besoin des en-têtes de requête et les renvoyer dans un en-tête de réponse Set-Cookie - et les cookies peuvent être lus en JavaScript. Comme le dit Keparo, cependant, il est préférable de ne le faire que pour un ou deux en-têtes plutôt que pour tous.

9
savetheclocktower

Si nous parlons d'en-têtes Request, vous pouvez créer vos propres en-têtes lorsque vous exécutez XmlHttpRequests.

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

Vous ne pouvez pas accéder aux en-têtes http, mais certaines des informations fournies sont disponibles dans le DOM. Par exemple, si vous voulez voir le référent http (sic), utilisez document.referrer. Il peut y en avoir d'autres comme celui-ci pour d'autres en-têtes http. Essayez de rechercher Google ce que vous voulez, comme "http javascript".

Je sais que cela devrait être évident, mais je continuais à chercher des choses comme "en-têtes http javascript" alors que tout ce que je voulais vraiment, c'était le référant et je n'ai obtenu aucun résultat utile. Je ne sais pas comment je n'ai pas réalisé que je pouvais faire une requête plus spécifique.

4
David Winiecki

En utilisant mootools, vous pouvez utiliser this.xhr.getAllResponseHeaders ()

3
aman

Comme beaucoup de gens, j'ai creusé le net sans réelle réponse :(

J'ai néanmoins trouvé un pont qui pourrait aider les autres. Dans mon cas, je contrôle totalement mon serveur Web. En fait, cela fait partie de mon application (voir fin de référence). Il est facile pour moi d'ajouter un script à ma réponse http. J'ai modifié mon serveur httpd pour injecter un petit script dans chaque page HTML. Je ne pousse qu'une ligne 'script js' supplémentaire juste après la construction de mon en-tête, qui définit une variable existante de mon document dans mon navigateur [Je choisis l'emplacement], mais toute autre option est possible. Bien que mon serveur soit écrit en nodejs, je n'ai aucun doute sur le fait que la même technique peut être utilisée à partir de PHP ou d'autres.

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

Désormais, toutes les pages html chargées depuis mon serveur font exécuter ce script par le navigateur à la réception. Je peux alors facilement vérifier à partir de JavaScript si la variable existe ou non. Dans mon cas d'utilisation, je dois savoir si je dois utiliser un profil JSON ou JSON-P pour éviter un problème CORS, mais la même technique peut être utilisée à d'autres fins (par exemple, choisir entre un serveur de développement/production, obtenir du serveur un REST/API clé, etc ....]

Sur le navigateur, il vous suffit de vérifier la variable directement à partir de JavaScript, comme dans mon exemple, où je l'utilise pour sélectionner mon profil 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);

Pour ceux qui voudraient vérifier mon code: https://www.npmjs.org/package/gpsdtracking

3
Fulup

Je viens de tester, et cela fonctionne pour moi avec Chrome Version 28.0.1500.95.

J'avais besoin de télécharger un fichier et de lire le nom du fichier. Le nom du fichier est dans l'en-tête, j'ai donc fait ce qui suit:

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 ++++++++");

    }
};

Sortie:

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
3
rushmore

Voici mon script pour obtenir tous les en-têtes de réponse:

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);

Ayant pour résultat les en-têtes de réponse.

enter image description here

Ceci est un test de comparaison utilisant Hurl.it:

enter image description here

2
Jorgesys

Pour obtenir les en-têtes comme un objet plus pratique (amélioration de réponse 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
shaedrich

C'est une vieille question. Vous ne savez pas quand le support est devenu plus large, mais getAllResponseHeaders() et getResponseHeader() semblent être maintenant assez standard: http://www.w3schools.com/xml/dom_http.asp

1
dlo