Доступ к HTTP-заголовкам веб-страницы в JavaScript - PullRequest
371 голосов
/ 21 октября 2008

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

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

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

Ответы [ 16 ]

345 голосов
/ 03 февраля 2011

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


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

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);
278 голосов
/ 21 октября 2008

К сожалению, нет 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, вы можете перебирать их на сервере и отправлять обратно как скрытые значения в разметке. Вероятно, не стоит отправлять значения заголовков таким образом, но вы, безусловно, можете сделать это для нужного вам значения. Это решение, возможно, тоже неэффективно, но оно бы сработало, если бы оно вам понадобилось.

27 голосов
/ 04 ноября 2008

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

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

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

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

16 голосов
/ 11 июня 2016

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

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

Как это работает:

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

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

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

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

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

Для тех, кто ищет способ разбить все заголовки HTTP на объект, к которому можно обращаться как к словарю 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"]
9 голосов
/ 21 октября 2008

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

5 голосов
/ 21 октября 2008

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

var request = new XMLHttpRequest();
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.open("GET", path, true);
request.send(null);
4 голосов
/ 30 января 2013

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

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

3 голосов
/ 15 октября 2014

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

Тем не менее, я нашел обходной путь, который мог бы помочь другим. В моем случае я полностью контролирую свой веб-сервер. На самом деле это часть моего приложения (см. Конец ссылки). Мне легко добавить скрипт в мой http-ответ. Я изменил свой httpd-сервер, чтобы внедрить небольшой скрипт в каждую 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-странице, загруженной с моего сервера, этот скрипт выполняется браузером при получении. Затем я могу легко проверить из JavaScript, существует ли переменная или нет. В моем сценарии использования мне нужно знать, должен ли я использовать профиль JSON или JSON-P, чтобы избежать проблемы с CORS, но эту же технику можно использовать для других целей [т.е. ключ и т.д ....]

В браузере вам просто нужно проверить переменную напрямую из 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

3 голосов
/ 16 августа 2013

Я только что протестировал, и это работает для меня, используя 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...