在 JavaScript 中访问网页的 HTTP 标头
无法读取当前标题。您可以向同一 URL 发出另一个请求并读取其标头,但不能保证标头与当前的完全相同。
使用以下 JavaScript 代码通过执行get
请求来获取所有 HTTP 标头:
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);
不幸的是,没有一个 API 可以为您提供初始页面请求的 HTTP 响应标头。那是张贴在这里的原始问题。它也被反复询问,因为有些人希望获得原始页面请求的实际响应头而不发出另一个。
对于 AJAX 请求:
如果通过 AJAX 发出 HTTP 请求,则可以使用该getAllResponseHeaders()
方法获取响应标头。它是 XMLHttpRequest API 的一部分。要了解如何应用它,请查看fetchSimilarHeaders()
下面的函数。请注意,这是对某些应用程序不可靠的问题的解决方法。
myXMLHttpRequest.getAllResponseHeaders();
该 API 在 XMLHttpRequest 的以下候选推荐中指定:XMLHttpRequest - W3C Candidate Recommendation 2010 年 8 月 3 日
具体而言,
getAllResponseHeaders()
:在下面的部分被指定方法w3.org:XMLHttpRequest
:该getallresponseheaders()
方法该MDN文档是好的,太:developer.mozilla.org:
XMLHttpRequest
。
这不会为您提供有关原始页面请求的 HTTP 响应标头的信息,但可用于对这些标头是什么进行有根据的猜测。更多相关内容将在接下来描述。
从初始页面请求中获取标头值:
这个问题在几年前首次被问到,专门询问如何获取当前页面(即运行 javascript 的同一页面)的原始 HTTP 响应标头。这与简单地获取任何 HTTP 请求的响应标头完全不同。对于初始页面请求,javascript 不容易获得标头。如果您通过 AJAX 再次请求同一页面,您需要的标头值是否可靠且足够一致将取决于您的特定应用程序。
以下是解决该问题的一些建议。
1. 对大部分静态资源的请求
如果响应主要是静态的,并且请求之间的标头不会有太大变化,您可以对当前所在的同一页面发出 AJAX 请求,并假设它们是相同的值,这些值是页面的一部分HTTP 响应。这可以允许您使用上述漂亮的 XMLHttpRequest API 访问所需的标头。
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. 进行推断
有一些BOM性质,其浏览器确定通过查看头(浏览器对象模型)。其中一些属性直接反映 HTTP 标头(例如navigator.userAgent
设置为 HTTPUser-Agent
标头字段的值)。通过嗅探可用的属性,您可能能够找到您需要的内容,或一些指示 HTTP 响应包含的内容的线索。
3. 藏起来
如果您控制服务器端,则可以在构建完整响应时访问您喜欢的任何标头。值可以通过页面传递给客户端,存储在一些标记中,或者可能是内联的 JSON 结构。如果您想让每个 HTTP 请求标头都可用于您的 javascript,您可以在服务器上遍历它们并将它们作为标记中的隐藏值发送回。以这种方式发送标头值可能并不理想,但您当然可以针对您需要的特定值来执行此操作。这个解决方案也可以说是低效的,但如果你需要它,它可以完成这项工作。
使用XmlHttpRequest
您可以拉出当前页面,然后检查响应的 http 标头。
最好的情况是只做一个HEAD
请求,然后检查标头。
有关这样做的一些示例,请查看http://www.jibbering.com/2002/4/httprequest.html
只有我的 2 美分。
Service Worker 的解决方案
服务工作者能够访问网络信息,其中包括标头。好的部分是它适用于任何类型的请求,而不仅仅是 XMLHttpRequest。
这个怎么运作:
- 在您的网站上添加 Service Worker。
- 观察正在发送的每个请求。
fetch
使用respondWith
函数向 service worker发出请求。- 当响应到达时,读取标题。
- 将来自 Service Worker 的标头发送到具有该
postMessage
函数的页面。
工作示例:
Service Worker 有点难以理解,所以我构建了一个小型库来完成所有这些工作。它可以在 github 上找到:https : //github.com/gmetais/sw-get-headers。
限制:
- 该网站需要使用HTTPS
- 浏览器需要支持Service Workers API
- 同域/跨域策略在起作用,就像在 XMLHttpRequest 上一样
另一种向 JavaScript 发送标头信息的方法是通过 cookie。服务器可以从请求头中提取它需要的任何数据,并将它们发送回Set-Cookie
响应头中——cookie 可以在 JavaScript 中读取。不过,正如 keparo 所说,最好只对一两个标题执行此操作,而不是对所有标题执行此操作。