Dostęp do nagłówków HTTP strony internetowej w JavaScript


406

Jak uzyskać dostęp do nagłówków odpowiedzi HTTP strony za pomocą JavaScript?

Powiązane z tym pytaniem , które zostało zmodyfikowane w celu uzyskania dostępu do dwóch określonych nagłówków HTTP.

Powiązane:
Jak uzyskać dostęp do pól nagłówka żądania HTTP za pomocą JavaScript?


@ user2284570 - Nie jest. to pytanie dotyczy nagłówków odpowiedzi , a nie nagłówków żądań .
Quentin,

Odpowiedzi:


365

Nie można odczytać bieżących nagłówków. Możesz złożyć kolejne żądanie do tego samego adresu URL i odczytać jego nagłówki, ale nie ma gwarancji, że nagłówki są dokładnie równe bieżącemu.


Użyj następującego kodu JavaScript, aby uzyskać wszystkie nagłówki HTTP, wykonując getżądanie:

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

58
Saeed, być może nie najlepszy dla autora pytania ... Myślę, że to dlatego, że nie ma dostępu do nagłówków załadowanego zasobu, ale
wysyła

18
W zależności od nagłówka, którego szukasz, możesz użyć czasownika „HEAD”.
szkocki

17
Złożenie nowego żądania będzie działać tylko wtedy, gdy gwarantowane wartości odpowiedzi będą identyczne dla jednego żądania do drugiego. Będzie to zależeć od twojej aplikacji, więc twój przebieg z takim podejściem będzie się różnić.
keparo

6
Ten hack może działać w niektórych scenariuszach, ale w ogóle nie będzie działać, jeśli strona zawierająca skrypt została wygenerowana w odpowiedzi na żądanie POST i nie pomaga, jeśli próbujesz ustalić, czy serwer napotkał błąd (HTTP 5XX) podczas przetwarzania pierwotnego żądania.
Claymation

9
Ta odpowiedź jest strasznie błędna. Prawidłowa odpowiedź to „to niemożliwe”. Lub dopasuj odpowiedź: „Nie jest to możliwe, ale oto próba zasymulowania tego, co może, ale nie musi, w ogóle działać”.
Jan

301

Niestety nie ma interfejsu API zapewniającego nagłówki odpowiedzi HTTP dla pierwszego żądania strony. To było pierwotne pytanie zadane tutaj. To pytanie też było wielokrotnie zadawane , ponieważ niektóre osoby chciałyby uzyskać nagłówki odpowiedzi na oryginalne żądanie strony bez wydawania kolejnego.


W przypadku żądań AJAX:

Jeśli przez AJAX zostanie wysłane żądanie HTTP, możliwe jest uzyskanie nagłówków odpowiedzi za pomocą tej getAllResponseHeaders()metody. Jest to część interfejsu API XMLHttpRequest. Aby zobaczyć, jak można to zastosować, sprawdź fetchSimilarHeaders()poniższą funkcję. Pamiętaj, że jest to obejście problemu, które nie będzie niezawodne w niektórych aplikacjach.

myXMLHttpRequest.getAllResponseHeaders();

Nie dostarczy Ci informacji na temat nagłówków odpowiedzi HTTP na żądanie strony, ale może być wykorzystany do wyuczonego odgadnięcia, jakie były te nagłówki. Więcej na ten temat opisano dalej.


Pobieranie wartości nagłówka z początkowego żądania strony:

To pytanie zostało po raz pierwszy zadane kilka lat temu, pytając konkretnie o to, jak uzyskać oryginalne nagłówki odpowiedzi HTTP dla bieżącej strony (tj. samej strony, na której działał javascript). To jest zupełnie inne pytanie niż po prostu uzyskanie nagłówków odpowiedzi dla dowolnego żądania HTTP. W przypadku pierwszego żądania strony nagłówki nie są łatwo dostępne w języku JavaScript. To, czy wartości nagłówków, których potrzebujesz, będą niezawodnie i wystarczająco spójne, jeśli ponownie zażądasz tej samej strony za pośrednictwem AJAX, będzie zależeć od konkretnej aplikacji.

Oto kilka sugestii dotyczących obejścia tego problemu.


1. Żądania dotyczące zasobów, które są w dużej mierze statyczne

Jeśli odpowiedź jest w dużej mierze statyczna, a nagłówki nie powinny się znacznie zmieniać między żądaniami, możesz złożyć żądanie AJAX dla tej samej strony, na której aktualnie się znajdujesz i założyć, że są to te same wartości, które były częścią strony Odpowiedź HTTP. To może pozwolić ci na dostęp do potrzebnych nagłówków przy użyciu ładnego interfejsu API XMLHttpRequest opisanego powyżej.

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

Takie podejście będzie problematyczne, jeśli naprawdę będziesz musiał polegać na wartościach spójnych między żądaniami, ponieważ nie możesz w pełni zagwarantować, że są one takie same. Będzie to zależeć od konkretnej aplikacji i tego, czy wiesz, że potrzebna wartość jest czymś, co nie będzie się zmieniać z jednego żądania do następnego.


2. Dokonaj wnioskowania

Istnieje kilka właściwości BOM (Browser Object Model), które przeglądarka określa na podstawie nagłówków. Niektóre z tych właściwości bezpośrednio odzwierciedlają nagłówki HTTP (np. Są navigator.userAgentustawione na wartość User-Agentpola nagłówka HTTP ). Wyszukując dostępne właściwości, możesz znaleźć to, czego potrzebujesz, lub kilka wskazówek, które wskazują, co zawiera odpowiedź HTTP.


3. Schowaj je

Jeśli kontrolujesz stronę serwera, możesz uzyskać dostęp do dowolnego nagłówka, który chcesz, podczas konstruowania pełnej odpowiedzi. Wartości mogą być przekazywane klientowi wraz ze stroną, ukryte w znacznikach lub być może we wbudowanej strukturze JSON. Jeśli chcesz mieć każdy nagłówek żądania HTTP dostępny w swoim javascript, możesz iterować je na serwerze i odsyłać jako ukryte wartości w znacznikach. Prawdopodobnie wysyłanie wartości nagłówka w ten sposób nie jest idealne, ale z pewnością można to zrobić dla określonej wartości, której potrzebujesz. To rozwiązanie jest również prawdopodobnie nieefektywne, ale wykonałoby zadanie, gdybyś go potrzebował.


2
Jak Google wykrywa to tak, jak wyjaśniłem tutaj: stackoverflow.com/questions/7191242/…
kamaci

Aktualizacja RE: żądania ajax były standardową częścią tworzenia stron WWW w 2008 roku, a także -_-
BlueRaja - Danny Pflughoeft

5
BOM oznacza „Browser Object Model” dla tych, którzy się zastanawiają. Zobacz stackoverflow.com/questions/2213594/... w celu uzyskania dodatkowych informacji.
Myrne Stol

1
3) możesz również ukryć je w nagłówku pliku cookie http. Wtedy nie trzeba zmieniać znaczników dokumentu.
skibulk

Istnieje prosty sposób na dostęp do elementów nagłówka odpowiedzi, takich jak element linku: skorzystaj z przykładu dokumentu tutaj: gist.github.com/FunThomas424242/…
FunThomas424242


24

Rozwiązanie z pracownikami serwisowymi

Pracownicy usług mogą uzyskać dostęp do informacji sieciowych, w tym nagłówków. Zaletą jest to, że działa na każdym rodzaju żądania, nie tylko XMLHttpRequest.

Jak to działa:

  1. Dodaj pracownika serwisu na swojej stronie.
  2. Obserwuj każdą wysyłaną prośbę.
  3. Zadaj pracownikowi obsługi fetchżądanie za pomocą respondWithfunkcji.
  4. Gdy nadejdzie odpowiedź, przeczytaj nagłówki.
  5. Wyślij nagłówki od pracownika serwisu na stronę z postMessagefunkcją.

Przykład roboczy:

Pracownicy usługowi są nieco skomplikowani do zrozumienia, więc zbudowałem małą bibliotekę, która to wszystko robi. Jest dostępny na github: https://github.com/gmetais/sw-get-headers .

Ograniczenia:

  • strona musi być na HTTPS
  • przeglądarka musi obsługiwać pracowników serwisu interfejs API
  • działają zasady tej samej domeny / między domenami, tak jak na XMLHttpRequest

12

Dla tych, którzy szukają sposobu na parsowanie wszystkich nagłówków HTTP w obiekt, do którego można uzyskać dostęp jako słownik headers["content-type"], stworzyłem funkcję 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

Innym sposobem przesłania informacji nagłówka do JavaScript są pliki cookie. Serwer może wyodrębnić potrzebne dane z nagłówków żądania i odesłać je z powrotem w Set-Cookienagłówku odpowiedzi - a pliki cookie można odczytać w JavaScript. Jak jednak mówi Keparo, najlepiej zrobić to dla jednego lub dwóch nagłówków, a nie dla wszystkich.


1
To podejście nadal wymaga kontrolowania serwera JS. Bez względu na to, jak przekazujesz te informacje, twój kod nagle stał się nieczytelny. Dlaczego nie stworzyć interfejsu API dla tego konkretnego żądania, aby uniknąć uszkodzenia żądania dotyczącego oryginalnego zasobu?
MST

5

Jeśli mówimy o nagłówkach żądania , możesz tworzyć własne nagłówki podczas wykonywania XmlHttpRequests.

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

ze względów bezpieczeństwa nie będzie można modyfikować nagłówka żądania w Mozilli. mxr.mozilla.org/mozilla1.8.0/source/extensions/xmlextras/base/…
user121196

1
Przed użyciem metody setRequestHeader () należy wywołać metodę open (). developer.mozilla.org/en/…
XP1

1
Dostęp w pierwotnym pytaniu dotyczy uzyskiwania nagłówków, a nie ustawiania nagłówków.
Timo Tijhof,

4

Nie możesz uzyskać dostępu do nagłówków http, ale niektóre informacje w nich zawarte są dostępne w DOM. Na przykład, jeśli chcesz zobaczyć odsyłacz http (sic), użyj document.referrer. Mogą istnieć inne takie jak w przypadku innych nagłówków http. Spróbuj googlować konkretną rzecz, na którą chcesz, na przykład „JavaScript referer javascript”.

Wiem, że to powinno być oczywiste, ale wciąż szukałem takich rzeczy jak „javascript nagłówków http”, kiedy tak naprawdę chciałem tylko odsyłacza i nie uzyskałem żadnych użytecznych wyników. Nie wiem, jak nie zdawałem sobie sprawy, że mogę zrobić bardziej szczegółowe zapytanie.


4

Jak wiele osób kopałem sieć bez prawdziwej odpowiedzi :(

Mimo to znalazłem obwodnicę, która mogłaby pomóc innym. W moim przypadku w pełni kontroluję mój serwer WWW. W rzeczywistości jest to część mojej aplikacji (patrz odniesienie końcowe). Łatwo jest mi dodać skrypt do mojej odpowiedzi http. Zmodyfikowałem mój serwer httpd, aby wstawić mały skrypt na każdej stronie HTML. Wypycham tylko dodatkową linię „skryptu js” zaraz po konstrukcji nagłówka, która ustawia zmienną z mojego dokumentu w mojej przeglądarce [wybieram lokalizację], ale każda inna opcja jest możliwa. Podczas gdy mój serwer jest napisany w nodejs, nie mam wątpliwości, że ta sama technika może być używana z PHP lub innych.

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

Teraz każda strona HTML ładowana z mojego serwera ma ten skrypt wykonywany przez przeglądarkę w recepcji. Następnie mogę łatwo sprawdzić w JavaScript, czy zmienna istnieje, czy nie. W moim przypadku muszę wiedzieć, czy powinienem użyć profilu JSON, czy JSON-P, aby uniknąć problemu z CORS, ale tę samą technikę można wykorzystać do innych celów [tj. Wybrać pomiędzy serwerem programistycznym / produkcyjnym, uzyskać z serwera REST / API klucz itp. ....]

W przeglądarce wystarczy sprawdzić zmienną bezpośrednio z JavaScript, jak w moim przykładzie, gdzie używam jej do wyboru mojego profilu 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);

Dla tych, którzy chcieliby sprawdzić mój kod: https://www.npmjs.org/package/gpsdtracking


3

Używając mootools, możesz użyć this.xhr.getAllResponseHeaders ()


3

Właśnie przetestowałem i działa to dla mnie w wersji Chrome 28.0.1500.95.

Musiałem pobrać plik i odczytać nazwę pliku. Nazwa pliku znajduje się w nagłówku, więc wykonałem następujące czynności:

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

    }
};

Wynik:

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

To jest mój skrypt, aby uzyskać wszystkie nagłówki odpowiedzi:

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

Mając w rezultacie nagłówki odpowiedzi.

wprowadź opis zdjęcia tutaj

To jest test porównawczy z użyciem Hurl.it:

wprowadź opis zdjęcia tutaj


2

Aby uzyskać nagłówki jako obiekt, który jest wygodniejszy (poprawa odpowiedzi 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

Link Allaina Lalonde'a sprawił, że mój dzień. Wystarczy dodać tutaj prosty, działający kod HTML.
Działa z każdą rozsądną przeglądarką od wieków plus IE9 + i 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>

Uwaga: Otrzymujesz nagłówki drugiego żądania, wynik może różnić się od początkowego żądania.


Innym sposobem
jest bardziej nowoczesny fetch()interfejs API
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
Na caniuse.com jest obsługiwany przez Firefox 40, Chrome 42, Edge 14, Safari 11
Przykład roboczy kod:

<!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

To jest stare pytanie. Nie wiesz, kiedy stał się bardziej szerokie wsparcie, ale getAllResponseHeaders()i getResponseHeader()wydają się być teraz dość standardowe: http://www.w3schools.com/xml/dom_http.asp


50
getAllResponseHeaders () i getResponseHeader () są metodami obiektu XMLHttpRequest. Tj. Dla żądań ajax. Nie można używać tych metod do wyświetlania nagłówków strony początkowej - to, jak myślę, pierwotne pytanie naprawdę zadawało.
asgeo1

-1

Jak już wspomniano, jeśli kontrolujesz stronę serwera, powinna istnieć możliwość wysłania początkowych nagłówków żądania z powrotem do klienta w początkowej odpowiedzi.

Na przykład w programie Express działają następujące elementy:

app.get('/somepage', (req, res) => { res.render('somepage.hbs', {headers: req.headers}); }) Nagłówki są następnie dostępne w szablonie, więc mogą być ukryte wizualnie, ale uwzględnione w znacznikach i odczytane przez javascript po stronie klienta.


Pytanie dotyczy nagłówków odpowiedzi , a nie nagłówków żądań.
Quentin,

-1

Myślę, że pytanie poszło w niewłaściwy sposób. Jeśli chcesz pobrać nagłówek żądania z JQuery / JavaScript, odpowiedź jest po prostu nie. Inne rozwiązania to utworzenie strony aspx lub strony jsp, dzięki czemu możemy łatwo uzyskać dostęp do nagłówka żądania. Weź wszystkie żądania na stronie aspx i umieść w sesji / ciasteczkach, aby uzyskać dostęp do ciasteczek na stronie JavaScript.


1
Pytanie dotyczy odczytu nagłówków odpowiedzi . Wymienia nagłówki żądania tylko w kontekście potencjalnie powiązanego pytania.
Quentin,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.