Как получить доступ к заголовкам HTTP-ответов страницы через JavaScript?
Относится к этот вопрос, который был изменен, чтобы запрашивать доступ к двум конкретным заголовкам HTTP.
Related:
How do I access the HTTP request header fields via JavaScript?
Хотя вы не можете подготовить любые заголовки ответа HTML в JS, вы может читаете заголовок Server-Timing, и вы можете передавать через него произвольные данные ключ-значение. См. мой ответ.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


К сожалению, не существует API, который предоставил бы вам заголовки HTTP-ответа для вашего начального запроса страницы. Это был исходный вопрос, размещенный здесь. Это тоже было неоднократно спрашивал, потому что некоторые люди хотели бы получить фактические заголовки ответа исходного запроса страницы, не отправляя другой.
Если HTTP-запрос выполняется через AJAX, можно получить заголовки ответа с помощью метода getAllResponseHeaders(). Это часть API XMLHttpRequest. Чтобы увидеть, как это можно применить, ознакомьтесь с функцией fetchSimilarHeaders() ниже. Обратите внимание, что это решение проблемы, которое не будет надежным для некоторых приложений.
myXMLHttpRequest.getAllResponseHeaders();
API был указан в следующей рекомендации кандидата для XMLHttpRequest: XMLHttpRequest - рекомендация кандидата W3C 3 августа 2010 г.
В частности, метод getAllResponseHeaders() был указан в следующем разделе: w3.org: XMLHttpRequest: метод getallresponseheaders()
Документация MDN тоже хороша: developer.mozilla.org: XMLHttpRequest.
Это не даст вам информации о заголовках HTTP-ответа исходного запроса страницы, но его можно использовать для обоснованного предположения о том, что это за заголовки. Подробнее об этом рассказывается далее.
Этот вопрос впервые был задан несколько лет назад, в частности, как получить исходные заголовки HTTP-ответа для текущая страница (т.е. ту же страницу, внутри которой был запущен javascript). Это совсем другой вопрос, чем просто получение заголовков ответа на любой HTTP-запрос. Для исходного запроса страницы заголовки недоступны для javascript. Будет ли нужные вам значения заголовка надежно и достаточно согласованными, если вы снова запросите ту же страницу через AJAX, будет зависеть от вашего конкретного приложения.
Ниже приведены несколько советов по решению этой проблемы.
Если ответ в основном статический и не ожидается, что заголовки сильно изменятся между запросами, вы можете сделать запрос 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);
}
Этот подход будет проблематичным, если вам действительно придется полагаться на согласованность значений между запросами, поскольку вы не можете полностью гарантировать, что они одинаковы. Это будет зависеть от вашего конкретного приложения и от того, знаете ли вы, что нужное вам значение не будет меняться от одного запроса к другому.
Есть некоторые свойства спецификации (объектная модель браузера), которую браузер определяет, просматривая заголовки. Некоторые из этих свойств напрямую отражают заголовки HTTP (например, для navigator.userAgent установлено значение поля заголовка HTTP User-Agent). Обнюхивая доступные свойства, вы можете найти то, что вам нужно, или некоторые подсказки, чтобы указать, что содержится в ответе HTTP.
Если вы контролируете сторону сервера, вы можете получить доступ к любому заголовку, который вам нравится, при построении полного ответа. Значения могут быть переданы клиенту вместе со страницей, спрятаны в некоторой разметке или, возможно, во встроенной структуре JSON. Если вы хотите, чтобы каждый заголовок HTTP-запроса был доступен для вашего javascript, вы могли бы перебирать их на сервере и отправлять их обратно как скрытые значения в разметке. Вероятно, это не идеальный вариант для отправки значений заголовков таким образом, но вы, безусловно, можете сделать это для конкретного значения, которое вам нужно. Возможно, это решение тоже неэффективно, но оно сработает, если вам это нужно.
Как Google обнаруживает это, как я объяснил здесь: stackoverflow.com/questions/7191242/…
Обновление RE: запросы ajax были стандартной частью веб-разработки еще в 2008 году -_-
Для тех, кому интересно, BOM расшифровывается как «объектная модель браузера». См. stackoverflow.com/questions/2213594/… для некоторой предыстории.
3) вы также можете спрятать их в заголовке http cookie. Тогда вам не нужно будет менять разметку документа.
Есть простой способ получить доступ к элементам заголовка ответа, таким как элемент ссылки: используйте здесь пример документа: gist.github.com/FunThomas424242/…
Если ваша страница отображается с использованием html-шаблонов и вы управляете серверным кодом, вы можете спрятать переменные в скрытый div, который javascript может считывать в переменную. <div id = 'myvar' class = 'hide'> {{myvar}} </div>
URL-адрес @ Huluvu424242 выдает 404
@Kumar - спасибо за подсказку. Я сменил пользователя для развертываний. Итак, ссылка теперь: gist.github.com/Huluvu424242/…
Просто добавьте к этому. Теперь вы можете сделать это с помощью функции fetch (), которая поддерживается в Chrome, Edge и Firefox. stevemiller.dev/2019/…
Другой способ отправить информацию заголовка в JavaScript - это файлы cookie. Сервер может извлекать любые данные из заголовков запроса и отправлять их обратно в заголовке ответа Set-Cookie, а файлы cookie можно читать в JavaScript. Однако, как говорит Кепаро, лучше сделать это только для одного или двух заголовков, а не для всех.
Этот подход по-прежнему требует, чтобы вы контролировали сервер для вашего JS. Независимо от того, как вы передаете эту информацию, ваш код внезапно стал некэшируемым. Почему бы просто не создать API для этого конкретного запроса, чтобы не повредить запрос на исходный актив?
Если мы говорим о заголовках Запрос, вы можете создавать свои собственные заголовки при выполнении XmlHttpRequests.
var request = new XMLHttpRequest();
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.open("GET", path, true);
request.send(null);
вы не сможете изменить заголовок запроса в Mozilla по соображениям безопасности. mxr.mozilla.org/mozilla1.8.0/source/extensions/xmlextras/bas e /…
Вы должны вызвать open () перед использованием метода setRequestHeader (). developer.mozilla.org/en/…
В исходном вопросе Access - это получение заголовков, а не установка заголовков.
Используя XmlHttpRequest, вы можете открыть текущую страницу, а затем изучить http-заголовки ответа.
В лучшем случае просто выполните запрос HEAD, а затем изучите заголовки.
Некоторые примеры этого можно найти в http://www.jibbering.com/2002/4/httprequest.html.
Только мои 2 цента.
Именно то, о чем я думал
Используя mootools, вы можете использовать this.xhr.getAllResponseHeaders ()
Это старый вопрос. Не уверен, когда поддержка стала более широкой, но getAllResponseHeaders() и getResponseHeader() теперь кажутся довольно стандартными: http://www.w3schools.com/xml/dom_http.asp
getAllResponseHeaders () и getResponseHeader () - это методы объекта XMLHttpRequest. Т.е. для запросов ajax. Вы не можете использовать эти методы для просмотра заголовков начальной страницы - это то, что, я думаю, действительно задавал исходный вопрос.
Невозможно прочитать текущие заголовки. Вы можете сделать еще один запрос к тому же URL-адресу и прочитать его заголовки, но нет гарантии, что заголовки в точности равны текущему.
Используйте следующий код JavaScript, чтобы получить все заголовки HTTP, выполнив запрос get:
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);
Саид, может быть, не лучший вариант для автора вопроса ... Я думаю, это потому, что он не обращается к заголовкам загруженного ресурса, а делает новый запрос ... очевидно, он знает лучше всех, какой лучший ответ, и сделал его сам
Я бы подумал о том, чтобы пометить это, чтобы модератор мог правильно отметить. Отвечает на проблему, как указано.
В зависимости от того, какой заголовок вы идете после, вы можете использовать глагол «HEAD».
Я считаю, что заголовки файлов cookie опущены.
можете ли вы изменить заголовок ответа, чтобы браузер действовал определенным образом
Создание нового запроса будет работать только в том случае, если необходимые вам значения ответа будут идентичны от одного запроса к другому. Это будет зависеть от вашего приложения, поэтому ваш опыт при таком подходе будет отличаться.
Этот взлом может сработать в некоторых сценариях, но он не будет работать вообще, если страница, содержащая сценарий, была сгенерирована в ответ на запрос POST, и не поможет, если вы пытаетесь определить, обнаружил ли сервер ошибку. (HTTP 5XX) при обработке исходного запроса.
Также есть GetResponseHeader('headerName'), если вас интересует только значение одного заголовка, что, на мой взгляд, является наиболее распространенным вариантом использования.
Этот ответ ужасно неверен. Правильный ответ - «это невозможно». Или, чтобы соответствовать этому ответу: «Это невозможно, но вот хак, чтобы попытаться смоделировать это, которое может или не может работать для вас вообще».
Я видел людей, которые просили разъяснений по этому и связанным с ним вопросам ... * почему * браузер не может получить доступ к текущим заголовкам страниц? Есть ли где-нибудь спецификация браузера, в которой сказано «нет» и, возможно, объясняется причина?
Вы не можете получить доступ к заголовкам http, но некоторая информация, представленная в них, доступна в DOM. Например, если вы хотите увидеть http referer (sic), используйте document.referrer. Для других заголовков http могут быть и другие подобные. Попробуйте поискать в Google конкретную вещь, например "http referer javascript".
Я знаю, что это должно быть очевидно, но я продолжал искать такие вещи, как «http headers javascript», когда все, что мне действительно нужно, это реферер, и не получил никаких полезных результатов. Не знаю, как я не понял, что могу задать более конкретный запрос.
Я только что протестировал, и у меня это работает с использованием 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.info("++++++ reading headers ++++++++");
var headers = xhr.getAllResponseHeaders();
console.info(headers);
console.info("++++++ 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
Как и многие люди, я копался в сети без реального ответа :(
Тем не менее, я нашел обходной путь, который может помочь другим. В моем случае я полностью контролирую свой веб-сервер. Фактически это часть моего приложения (см. Конец ссылки). Мне легко добавить скрипт в свой 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, но тот же метод можно использовать для других целей [например: выбор между сервером разработки / производства, получение с сервера 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
Сервисные работники могут получить доступ к сетевой информации, включая заголовки. Хорошо то, что он работает с любым запросом, а не только с XMLHttpRequest.
fetch с помощью функции respondWith.postMessage.Сервис-воркеры немного сложны для понимания, поэтому я создал небольшую библиотеку, которая делает все это. Он доступен на github: https://github.com/gmetais/sw-get-headers.
Для тех, кто ищет способ преобразовать все заголовки 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"]
Это мой сценарий для получения всех заголовков ответов:
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);
Получив в результате заголовки ответа.
Это сравнительный тест с использованием Hurl.it:
Как уже упоминалось, если вы контролируете серверную часть, тогда должна быть возможность отправить первоначальные заголовки запроса обратно клиенту в первоначальном ответе.
В Express, например, работает следующее:
app.get('/somepage', (req, res) => {
res.render('somepage.hbs', {headers: req.headers});
})
Заголовки становятся доступными в шаблоне, поэтому их можно скрыть визуально, но включить в разметку и прочитать клиентским javascript.
Вопрос касается заголовков отклик, а не заголовков запросов.
Чтобы получить заголовки как более удобный объект (улучшение Ответ раджи):
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.info(headers);
Я думаю, вопрос задан неверно, Если вы хотите получить заголовок запроса из JQuery / JavaScript, ответ будет просто Нет. Другие решения - создать страницу aspx или страницу jsp, тогда мы сможем легко получить доступ к заголовку запроса. Возьмите весь запрос на странице aspx и поместите в сеанс / файлы cookie, после чего вы сможете получить доступ к файлам cookie на странице JavaScript ..
Вопрос в том, чтобы прочитать заголовки отклик. Заголовки запроса упоминаются только в контексте, возможно, связанного вопроса.
Ссылка Аллена Лалонда сделала мой день лучше.
Просто добавьте сюда простой рабочий HTML-код.
Работает с любым разумным браузером с давних времен, плюс IE9 + и 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>
Примечание: вы получаете заголовки второго запроса, результат может отличаться от исходного запроса.
fetch() API
<!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>
Хотя в целом не может читать произвольные заголовки HTTP-ответа HTML-навигации верхнего уровня, если вы управляете сервером (или промежуточными ящиками в пути) и хотите предоставить JavaScript некоторую информацию, которую нельзя легко раскрыть другим способом чем через заголовок:
Вы можете использовать заголовок Server-Timing для предоставления произвольных данных "ключ-значение", и он будет доступен для чтения JavaScript.
(* в поддерживаемых браузерах: Firefox 61, Chrome 65, Edge 79; Safari еще нет с 2021.02; нет IE)
Пример:
server-timing: key;desc = "value"
server-timing: key1;desc = "value1"
server-timing: key2;desc = "value2"
server-timing: key1;desc = "value1", key2;desc = "value2"
Пример того, как Википедия использует этот заголовок для предоставления информации о попаданиях / промахах в кеш:
Пример кода (необходимо учитывать отсутствие поддержки браузеров в Safari и IE):
if (window.performance && performance.getEntriesByType) { // avoid error in Safari 10, IE9- and other old browsers
let navTiming = performance.getEntriesByType('navigation')
if (navTiming.length > 0) { // still not supported as of Safari 14...
let serverTiming = navTiming[0].serverTiming
if (serverTiming && serverTiming.length > 0) {
for (let i=0; i<serverTiming.length; i++) {
console.info(`${serverTiming[i].name} = ${serverTiming[i].description}`)
}
}
}
}
Это регистрирует cache = hit-front в поддерживаемых браузерах.
Заметки:
Timing-Allow-Origin: * или Timing-Allow-Origin: https://www.example.com)Server-Timing поддерживают также поле dur (заголовок), читаемое как duration на стороне JS, но это необязательно и по умолчанию используется 0 в JS, если не переданоPerformanceObserver API. Подробнее см. Сообщение блога.
@ user2284570 - Нет. этот вопрос касается заголовков отклик, а не заголовков запрос.