- 原文地址:The headers we don't want
- 原文做者:Andrew Betts
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:Ethan
- 校对者:Hank
若是你想了解更多 http 头信息的知识,请关注 5 月 22 号安德鲁在伦敦的演讲。html
http 头信息是控制缓存和浏览器处理web内容的一种重要方式。但不少时候它都被错误或冗余地使用,这不只没有达成咱们的使用目的,还增长了加载页面时的运行开销。这篇 http 头信息的系列博文中的第一篇文章,让咱们先来扒一扒那些没必要要的 http 头信息。前端
大多数开发者都了解一些 HTTP 头信息,并利用它去处理内容。如你们熟知的 Content-Type
和 Content-Length
,它们都是通用的。但最近,Content-Security-Policy
和 Strict-Transport-Security
这样的头信息已经开始用于提升安全性,Link rel=preload
用于提升性能。只是极少数网站使用他们,尽管它们被浏览器普遍支持。android
与此同时,还有不少之前就有而且灰常受欢迎的头信息是不实用的。咱们可使用 HTTP 存档 来证明这一点。HTTP 存档 是由 Fastly 赞助并由 Google 运营的项目,每月使用 WebPageTest 加载 500,000 个网站并进行性能测试,结果公布在 BigQuery。ios
在 HTTP 存档数据中,这里列出了 30 个最受欢迎的响应头信息(基于存档中大多数网站都处理的头信息进行统计的结果),并大体说说它们多有用:nginx
Header name | Requests | Domains | Status |
---|---|---|---|
date | 48779277 | 535621 | Required by protocol |
content-type | 47185627 | 533636 | Usually required by browser |
server | 43057807 | 519663 | Unnecessary |
content-length | 42388435 | 519118 | Useful |
last-modified | 34424562 | 480294 | Useful |
cache-control | 36490878 | 412943 | Useful |
etag | 23620444 | 412370 | Useful |
content-encoding | 16194121 | 409159 | Required for compressed content |
expires | 29869228 | 360311 | Unnecessary |
x-powered-by | 4883204 | 211409 | Unnecessary |
pragma | 7641647 | 188784 | Unnecessary |
x-frame-options | 3670032 | 105846 | Unnecessary |
access-control-allow-origin | 11335681 | 103596 | Useful |
x-content-type-options | 11071560 | 94590 | Useful |
link | 1212329 | 87475 | Useful |
age | 7401415 | 59242 | Useful |
x-cache | 5275343 | 56889 | Unnecessary |
x-xss-protection | 9773906 | 51810 | Useful |
strict-transport-security | 4259121 | 51283 | Useful |
via | 4020117 | 47102 | Unnecessary |
p3p | 8282840 | 44308 | Unnecessary |
expect-ct | 2685280 | 40465 | Useful |
content-language | 334081 | 37927 | Debatable |
x-aspnet-version | 676128 | 33473 | Unnecessary |
access-control-allow-credentials | 2804382 | 30346 | Useful |
x-robots-tag | 179177 | 24911 | Not relevant to browsers |
x-ua-compatible | 489056 | 24811 | Useful |
access-control-allow-methods | 1626129 | 20791 | Useful |
access-control-allow-headers | 1205735 | 19120 | Useful |
咱们这里只关注那些不须要的头信息,以及说明为何不须要它们、该如何处理。git
你可能为你服务器软件的选择而骄傲,可是大多数人(用户)对此并不关心。而且这些头部信息可能会致使你的敏感信息泄漏进而使得你的网站受到攻击。github
Server: apache
X-Powered-By: PHP/5.1.1
Via: 1.1 varnish, 1.1 squid
复制代码
RFC7231 标准容许服务器在响应中包含 Server
头信息,识别用于服务内容的服务器软件。最多见的是 “apache” 和 “nginx”。虽然它是容许的,也不是强制的,可是对开发者和最终用户都没有太多实在乎义。然而,它是当今 web 上第三个最流行的 HTTP 响应头。web
X-Powered-By
是没有在任何标准中定义却很受欢迎的头信息,类似地,一般用于指出 web 服务器后的应用软件平台。常见的值有 “ASP.net”,“PHP” 和 “Express”,实际上它们并不提供任何好处,还占用空间。apache
更具争议的应该是 Via
,当添加到经过其传递的代理来识别代理的任何代理的响应时,RFC7230 规定它是必须的。代理主机名的时候他多是有用的,但更多时候它像是一个通用标识符,如 “vegur”,“varnish”,或 “squid”。删除或者不设置这个头信息在技术上是违反规范的,可是没有浏览器对它作任何事情,因此若是你想删除它是没问题的。后端
另外一类 http 头信息是那些在浏览器中有效果的,但不是(或者再也不是)达成效果的最佳方式。
P3P: cp="this is not a p3p policy"
Expires: Thu, 01 Dec 1994 16:00:00 GMT
X-Frame-Options: SAMEORIGIN
复制代码
P3P
是个让人好奇的东东。我对它不了解,甚至很好奇,它最多见的值竟然是 “this is not a p3p policy”。那它是,仍是不是啊?
这要追溯到试图使机器可读的隐私政策标准化,当时你们对于如何在浏览器中显示数据存在分歧,而且只有一个浏览器实现了这个 http 头信息 -- IE 浏览器。即便在 IE 浏览器中,P3P
也不会给用户带去任何视觉效果,它只须要在 iframe 中容许访问第三方cookie。有些网站甚至设置了一个不符合标准的 P3P 规则,好比上面的一个,即便这样作是不合法律规定的。
不用说,读取第三方 cookie 一般是不可取的,因此若是你打算不这样作,你也不须要设置一个 P3P
头信息
Expires
受欢迎程度达到了难以想象的情况,试想下这种状况,Cache-Control
被设置为 20 年后过时。若是 Cache-Control
头信息包含 max-age
指令,那么在相同响应上的任何 Expires
头信息将被忽略。可是有大量网站同时设置了这两个信息,而且 Expires
头信息一般被设置为格林尼治时间 -- Thu, 01 Dec 1994 16:00:00
。不少人这样作由于他们不但愿网站内容被缓存和复制,因此就从规范中复制这个实例日期来填充。
实际上咱们不必这么作。若是你设置了一个 Expires
头信息并为其设置了一个过往的时间,那么你能够这么设置,用来取代你以前的作法:
Cache-Control: no-cache, private
复制代码
一些审核你网站的工具会让你添加一个值为 “SAMEORIGIN” 的 X-Frame-Options
头信息。这告诉浏览器你拒绝被其余网站诬告,这也是预防点击攻击的一种经常使用手段。 然而,如下更一致的支持和更可靠的行为定义的方式,能够实现一样的效果:
Content-Security-Policy: frame-ancestors 'self'
复制代码
做为头信息(csp)的一部分,你还得到其余好处(稍后会详细介绍)。因此你如今可能没有 X-Frame-Options
头信息。
使人惊讶的是,一些最经常使用的头信息都没有任何标准。实际上,这意味着,成千上万的网站彷佛自发地赞成以特定的方式使用特定的 http 头信息。
X-Cache: HIT
X-Request-ID: 45a336c7-1bd5-4a06-9647-c5aab6d5facf
X-ASPNet-Version: 3.2.32
X-AMZN-RequestID: 0d6e39e2-4ecb-11e8-9c2d-fa7ae01bbebc
复制代码
实际上,这些“未知”头信息并非由网站开发人员独立完成的。它们一般是受使用特定服务器框架、软件或特定供应商服务的人为因素的影响而造成的(在此示例中,最后一个头信息是常见的 AWS 头信息)。
特别地,X-Cache
实际是 Fastly 添加的(其余 CDN 也是这样作的),其余一些与 Fastly 相关的头信息,如X-Cache-Hits
和 X-Served-By
。当启用调试时,咱们添加更多头信息,如 Fastly-Debug-Path
和 Fastly-Debug-TTL
。
这些头信息没法被任何浏览器识别,删除它们对网页渲染没有任何影响。可是,因为这些标题可能向开发人员提供有用的信息,所以你或许要保留一些方法来告知开发者。
我没料到会在 2018 年写一篇关于“Pragma”头的文章,但根据咱们的 HTTP 存档数据,它竟然还排在了第 11 位。早在 1997 年,Pragma 就已经弃用了,它也历来没有打算成为响应头 —— 正如所指定的,它只有做为请求的一部分时才有意义。
Pragma: no-cache
复制代码
尽管如此,它做为一个响应头是如此被普遍使用,以致于一些浏览器也能识别它。如今,你的回应将传递一个能识别 Pragma
的缓存,而不能识别 Cache-Control
的几率很小。若是你想确保某些东西没有被缓存,你只须要 Cache-Control: no-cache, private
。
排名前 30 的头信息中有一个是非浏览器的头信息。X-Robots-Tag
用于对付网络爬虫,好比 Google 和 Bing 的机器人。由于它对浏览器没有任何意义,全部你能够在须要应对爬虫的时候才设置这个头信息。与此同时带来的影响,多是使得测试变得困难,或者是违反了搜索引擎的服务条款。
最后,值得一提的是简单的错误。在一个请求中,Host
头信息存在是有道理的,可是若是它出如今响应中就说明极可能你的服务被错误地配置(我很想知道这是怎么产生的)。尽管如此,上文提到的 HTTP 存档仍是有 68 个网域返回了 Host
的头信息。
若是你的网站使用了 Fastly 的服务,那么恭喜你,使用 VCL 是删去头信息是很便捷的。你可能但愿将真正有用的调试数据保留到你的开发团队中,但将其隐藏在公共用户中,这颇有意义,你能够经过检测 cookie 或传进来 HTTP 头信息来轻松实现:
unset resp.http.Server;
unset resp.http.X-Powered-By;
unset resp.http.X-Generator;
if (!req.http.Cookie:debug && !req.http.Debug) {
unset resp.http.X-Amzn-RequestID;
unset resp.http.X-Cache;
}
复制代码
在本系列的下一篇文章中,我将讨论设置 HTTP 头信息的最佳作法,以及如何启用它们。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。