在 JavaScript 中访问网页的 HTTP 标头

IT技术 javascript http http-headers
2021-01-24 22:33:04

如何通过 JavaScript 访问页面的 HTTP 响应标头?

此问题相关,该问题已修改为询问有关访问两个特定 HTTP 标头的问题。

相关:
如何通过 JavaScript 访问 HTTP 请求标头字段?

6个回答

无法读取当前标题。您可以向同一 URL 发出另一个请求并读取其标头,但不能保证标头与当前的完全相同。


使用以下 JavaScript 代码通过执行get请求来获取所有 HTTP 标头

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);
根据您要使用的标题,您可能想要使用“HEAD”动词。
2021-03-14 22:33:04
仅当您需要的响应值从一个请求到下一个请求保证相同时,发出新请求才有效。这将取决于您的应用程序,因此您使用这种方法的里程会有所不同。
2021-03-27 22:33:04
Saeed,对于问题作者来说可能不是最好的..我猜是因为它没有访问加载资源的标头,而是发出了一个新请求..显然他知道最好的,最好的答案是什么,并且自己做了
2021-03-29 22:33:04
此 hack 可能在某些情况下有效,但如果包含脚本的页面是为响应 POST 请求而生成的,则它根本不起作用,并且如果您尝试确定服务器是否遇到错误,它也无济于事(HTTP 5XX) 同时处理原始请求。
2021-04-08 22:33:04
这个答案大错特错。正确答案是“这不可能”。或者为了适应这个答案“这是不可能的,但这里有一个尝试模拟它的技巧,它可能对你有用也可能根本不适合你”。
2021-04-08 22:33:04

不幸的是,没有一个 API 可以为您提供初始页面请求的 HTTP 响应标头。那是张贴在这里的原始问题。它也被反复询问,因为有些人希望获得原始页面请求的实际响应头而不发出另一个。


对于 AJAX 请求:

如果通过 AJAX 发出 HTTP 请求,则可以使用该getAllResponseHeaders()方法获取响应标头它是 XMLHttpRequest API 的一部分。要了解如何应用它,请查看fetchSimilarHeaders()下面函数。请注意,这是对某些应用程序不可靠的问题的解决方法。

myXMLHttpRequest.getAllResponseHeaders();

这不会为您提供有关原始页面请求的 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,您可以在服务器上遍历它们并将它们作为标记中的隐藏值发送回。以这种方式发送标头值可能并不理想,但您当然可以针对您需要的特定值来执行此操作。这个解决方案也可以说是低效的,但如果你需要它,它可以完成这项工作。

RE 更新:ajax 请求也是 2008 年 Web 开发的标准部分-_-
2021-03-14 22:33:04
3)您也可以将它们隐藏在 http cookie 标头中。那么您就不需要更改文档标记。
2021-03-19 22:33:04
有一种访问响应头元素(例如链接元素)的简单方法:在此处使用文档示例:gist.github.com/FunThomas424242/...
2021-03-21 22:33:04
BOM 代表“浏览器对象模型”,对于那些想知道的人。有关一些背景信息,请参阅stackoverflow.com/questions/2213594/...。
2021-03-26 22:33:04
Google 如何像我在这里解释的那样检测它:stackoverflow.com/questions/7191242/...
2021-03-29 22:33:04

使用XmlHttpRequest您可以拉出当前页面,然后检查响应的 http 标头。

最好的情况是只做一个HEAD请求,然后检查标头。

有关这样做的一些示例,请查看http://www.jibbering.com/2002/4/httprequest.html

只有我的 2 美分。

正是我想到的
2021-03-24 22:33:04

Service Worker 的解决方案

服务工作者能够访问网络信息,其中包括标头。好的部分是它适用于任何类型的请求,而不仅仅是 XMLHttpRequest。

这个怎么运作:

  1. 在您的网站上添加 Service Worker。
  2. 观察正在发送的每个请求。
  3. fetch使用respondWith函数向 service worker发出请求
  4. 当响应到达时,读取标题。
  5. 将来自 Service Worker 的标头发送到具有该postMessage函数的页面

工作示例:

Service Worker 有点难以理解,所以我构建了一个小型库来完成所有这些工作。它可以在 github 上找到:https : //github.com/gmetais/sw-get-headers

限制:

  • 该网站需要使用HTTPS
  • 浏览器需要支持Service Workers API
  • 同域/跨域策略在起作用,就像在 XMLHttpRequest 上一样
这很奇怪……我没有在 Service Worker 中丢失标头。我想那可能是因为我有相似的出身。我只需要在服务器上添加另一个标题res.set('Access-Control-Expose-Headers', 'page-size') stackoverflow.com/a/45608476/370238
2021-03-22 22:33:04
两个主要缺点... WKWebView 在最新的 safari 14 上不支持它。另一个问题是 Chrome Incognito 上有一个亮蓝色按钮,它也会禁用 Service Workers,因为大多数人使用它们来存储东西......而不是做关键工作。我现在只切换到工人......但我似乎缺少标题9v1li.csb.app
2021-04-08 22:33:04

另一种向 JavaScript 发送标头信息的方法是通过 cookie。服务器可以从请求头中提取它需要的任何数据,并将它们发送回Set-Cookie响应头中——cookie 可以在 JavaScript 中读取。不过,正如 keparo 所说,最好只对一两个标题执行此操作,而不是对所有标题执行此操作。

@MST 在我的情况下,我可以完全控制代理,但文件是完全静态部署的。Nginx 使更改标头变得微不足道。
2021-03-09 22:33:04
这种方法仍然需要你为你的 JS 控制服务器。无论您如何传达该信息,您的代码都会突然变得不可缓存。为什么不为该特定请求制作 API 以避免破坏对原始资产的请求?
2021-03-24 22:33:04