Доступ к HTTP-заголовкам веб-страницы в JavaScript

Как мне получить доступ к заголовкам HTTP-ответов HTTP через JavaScript?

Связано с этим вопросом, которое было изменено, чтобы спросить о доступе к двум конкретным HTTP-заголовкам.

Связанный:
Как получить доступ к полям заголовка запроса HTTP через JavaScript?

Ответ 1

К сожалению, нет API, который бы предоставил вам заголовки ответа HTTP для вашего начального запроса страницы. Это был оригинальный вопрос, размещенный здесь. Это также неоднократно задавалось, потому что некоторые люди хотели бы получить фактические заголовки ответа исходного запроса страницы без выдачи другого.


Для запросов AJAX:

Если HTTP-запрос сделан через AJAX, можно получить заголовки ответа с помощью getAllResponseHeaders(). Это часть API XMLHttpRequest. Чтобы увидеть, как это можно применить, проверьте fetchSimilarHeaders() ниже. Обратите внимание, что это обходной путь, который не будет надежным для некоторых приложений.

myXMLHttpRequest.getAllResponseHeaders();

Это не даст вам информацию об исходных HTTP-заголовках ответа на запрос страницы, но ее можно использовать для обоснованного предположения о том, какими были эти заголовки. Подробнее об этом описано далее.


Получение значений заголовка из запроса начальной страницы:

Этот вопрос впервые был задан несколько лет назад, в частности, спрашивался о том, как получить исходные заголовки ответа HTTP для текущей страницы (то есть той же самой страницы, внутри которой выполнялся javascript). Это совсем другой вопрос, чем просто получение заголовков ответов для любого HTTP-запроса. Для начального запроса страницы заголовки не всегда доступны для javascript. Будут ли значения заголовка, которые вам нужны, будут надежными и достаточно согласованными, если вы снова запросите ту же страницу через AJAX, будет зависеть от вашего конкретного приложения.

Ниже приведены несколько предложений по решению этой проблемы.


1. Запросы на ресурсы, которые в значительной степени статичны

Если ответ в значительной степени статичен, а заголовки не должны сильно меняться между запросами, вы можете сделать AJAX-запрос для той же страницы, на которой вы сейчас находитесь, и предположить, что это те же значения, которые были частью страницы. HTTP ответ. Это может позволить вам получить доступ к нужным заголовкам, используя красивый API XMLHttpRequest, описанный выше.

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

Этот подход будет проблематичным, если вам действительно придется полагаться на значения, согласованные между запросами, поскольку вы не можете полностью гарантировать, что они одинаковы. Это будет зависеть от вашего конкретного приложения и от того, знаете ли вы, что нужное вам значение не будет меняться от одного запроса к другому.


2. Сделайте выводы

Существуют некоторые свойства спецификации (объектная модель браузера), которые браузер определяет, просматривая заголовки. Некоторые из этих свойств напрямую отражают заголовки HTTP (например, navigator.userAgent имеет значение поля заголовка HTTP User-Agent). Обнюхивая доступные свойства, вы можете найти то, что вам нужно, или некоторые подсказки, чтобы указать, что содержится в HTTP-ответе.


3. Спрятать их

Если вы контролируете серверную часть, вы можете получить доступ к любому заголовку, который вам нравится, когда вы создаете полный ответ. Значения могут быть переданы клиенту со страницей, сохранены в некоторой разметке или, возможно, во встроенной структуре JSON. Если вы хотите, чтобы каждый заголовок HTTP-запроса был доступен для вашего javascript, вы можете перебирать их на сервере и отправлять обратно как скрытые значения в разметке. Вероятно, не стоит отправлять значения заголовков таким образом, но вы, безусловно, можете сделать это для нужного вам значения. Это решение, возможно, тоже неэффективно, но оно будет работать, если вам это нужно.

Ответ 2

Невозможно прочитать текущие заголовки. Вы можете сделать другой запрос на тот же URL-адрес и прочитать его заголовки, но нет гарантии, что заголовки точно равны текущему.


Используйте следующий код JavaScript, чтобы получить все заголовки HTTP, выполнив запрос get:

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

Ответ 3

Используя XmlHttpRequest, вы можете вытащить текущую страницу и затем изучить заголовки http ответа.

Лучшим случаем является просто выполнить запрос HEAD, а затем изучить заголовки.

Для некоторых примеров этого взгляните на http://www.jibbering.com/2002/4/httprequest.html

Только мои 2 цента.

Ответ 4

Решение с сервисными работниками

Сервисные работники имеют доступ к сетевой информации, которая включает заголовки. Хорошей частью является то, что он работает с любыми запросами, а не только с XMLHttpRequest.

Как это устроено:

  1. Добавьте работника сервиса на свой сайт.
  2. Смотреть каждый запрос, который отправляется.
  3. Заставьте сервисного работника fetch запрос с respondWith функции respondWith.
  4. Когда ответ придет, прочитайте заголовки.
  5. Отправьте заголовки от сервисного работника на страницу с функцией postMessage.

Рабочий пример:

Работники сферы обслуживания немного сложны для понимания, поэтому я создал небольшую библиотеку, которая делает все это. Он доступен на github: https://github.com/gmetais/sw-get-headers.

Ограничения:

  • сайт должен быть на HTTPS
  • браузер должен поддерживать API Service Workers
  • действуют те же доменные/междоменные политики, что и в XMLHttpRequest

Ответ 5

Другой способ отправить информацию заголовка на JavaScript будет через файлы cookie. Сервер может извлекать все необходимые данные из заголовков запросов и отправлять их обратно в заголовок ответа Set-Cookie, а файлы cookie могут быть прочитаны в JavaScript. Однако, как говорит кепаро, лучше всего сделать это только для одного или двух заголовков, а не для всех.

Ответ 6

Для тех, кто ищет способ разобрать все HTTP-заголовки в объект, доступ к которому можно получить в качестве headers["content-type"] словарей headers["content-type"], я создал функцию 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"]

Ответ 7

Если мы говорим о заголовках запроса, вы можете создавать свои собственные заголовки при выполнении XmlHttpRequests.

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

Ответ 8

Вы не можете получить доступ к заголовкам http, но часть предоставленной информации доступна в DOM. Например, если вы хотите увидеть http-референт (sic), используйте document.referrer. Могут быть и другие подобные для других заголовков http. Попробуйте выполнить поиск по конкретной теме, например "http referer javascript".

Я знаю, что это должно быть очевидно, но я продолжал искать такие вещи, как "http headers javascript", когда все, что я действительно хотел, было реферистом, и не получил никаких полезных результатов. Я не знаю, как я не понимал, что могу сделать более конкретный запрос.

Ответ 9

Используя mootools, вы можете использовать this.xhr.getAllResponseHeaders()

Ответ 10

Я только что протестировал, и это работает для меня с помощью Chrome версии 28.0.1500.95.

Мне нужно было скачать файл и прочитать имя файла. Имя файла находится в заголовке, поэтому я сделал следующее:

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

    }
};

Вывод:

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

Ответ 11

Как и многие люди, я копаю сеть без реального ответа: (

Я все же узнал обход, который мог бы помочь другим. В моем случае я полностью контролирую свой веб-сервер. На самом деле это часть моего приложения (см. Ссылку на конец). Мне легко добавить script в мой HTTP-ответ. Я модифицировал свой httpd-сервер, чтобы ввести небольшой script в каждый HTML-страницы. Я просто нажимаю лишнюю строку "js script" сразу после моей конструкции заголовка, которая устанавливает существующую переменную из моего документа в моем браузере [я выбираю местоположение], но возможен любой другой вариант. Хотя мой сервер написан в nodejs, я не сомневаюсь, что тот же метод может быть использован с PHP или другими.

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

Теперь каждая страница html, загруженная с моего сервера, имеет этот script, выполняемый браузером на приеме. Затем я могу легко проверить JavaScript, если переменная существует или нет. В моем случае я должен знать, должен ли я использовать профиль JSON или JSON-P, чтобы избежать проблемы CORS, но тот же метод можно использовать для других целей [т.е.: выбирать между сервером разработки/производства, получать с сервера REST/API ключ и т.д.).

В браузере вам просто нужно проверить переменную непосредственно из JavaScript, как в моем примере, где я использую его для выбора моего профиля 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);

Для тех, кто хотел бы проверить мой код: https://www.npmjs.org/package/gpsdtracking

Ответ 12

Это старый вопрос. Не уверен, когда поддержка стала более широкой, но теперь getAllResponseHeaders() и getResponseHeader() выглядят довольно стандартными: http://www.w3schools.com/xml/dom_http.asp

Ответ 13

Это мой сценарий, чтобы получить все заголовки ответов:

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

Имея в результате заголовки ответов.

enter image description here

Это сравнительный тест с использованием Hurl.it:

enter image description here

Ответ 14

Чтобы получить заголовки как объект, который более удобен (улучшение ответа Раджи):

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

Ответ 15

Как уже упоминалось, если вы контролируете серверную сторону, тогда должно быть возможно отправить исходные заголовки запросов обратно клиенту в первоначальном ответе.

В Express, например, следующие работы:

app.get('/somepage', (req, res) => { res.render('somepage.hbs', {headers: req.headers}); }) Затем заголовки доступны в шаблоне, так что может быть скрытый визуально, но включенный в разметку и прочитанный клиентским javascript.

Ответ 16

Я думаю, что вопрос пошел не так, если вы хотите взять заголовок запроса из JQuery/JavaScript, ответ просто Нет. Другие решения - это создать страницу aspx или страницу jsp, тогда мы сможем легко получить доступ к заголовку запроса. Возьмите весь запрос на странице aspx и поместите в сеанс/файлы cookie, затем вы можете получить доступ к файлам cookie на странице JavaScript.