可能很多人不知道http头部有什么作用,甚至一看到这些密密麻麻的头部信息,赶紧敬而远之。同学~你知道你犯了多大的错误吗?了解http头部,可以让你网站的性能得到很大的提升。
现在开始还来得及,赶紧往下看吧~
HTTP内容编码
内容编码目的是优化传输内容大小,通俗地讲就是进行压缩。
Accept-Encoding: 浏览器发给服务器,声明浏览器支持的编码类型
Content-Encoding:服务器返回的对应的类型编码。其值类型包括:- gzip 实体采用GUN zip编码
- compress 实体采用Unix的文件压缩程序
- deflate 采用zlib的格式压缩
- identity 没有对实体进行编码
gzip, compress, 以及deflate编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息损失。 其中gzip通常效率最高, 使用最为广泛。一般经过 gzip 压缩过的文本响应,只有原始大小的 1/4。
Expires
控制缓存失效的时间。
如果浏览器接收到的响应中有一个Expires头时,它会和相应的组件一起保存到缓存中,只要组件没有过期,浏览器就会使用缓存版本而不会进行任何的HTTP请求。
Expires设置的日期格式必须为GMT(格林尼治标准时间),必须是一个具体的时间,如:Expires: Fri, 30 Oct 1998 14:19:41。缺陷:
1、Web服务器的时间和缓存服务器的时间必须是同步的,如果有些不同步, 要么是应该缓存的内容提前过期了,要么是过期结果没及时更新。2、假如Expires的日期到了,那么还需要在服务器配置中提供一个新的日期,如果响应头没有更新下次过期的时间,那么之后所有请求都会被发送给源服务器Modified
If-Modified-Since: 浏览器将资源文件最后的修改时间发送给服务器
Last-Modified:资源文件最后的修改时间如下图,第一次请求资源的时候,服务器返回状态码200,响应Last-Modified,浏览器将其和资源一并保存到缓存
当浏览器再次发起请求的时候,会发送 If Modified Since头,这个时间就是缓存文件的 Last Modified 。也可以说,如果请求头包含 If Modified Since,就说明客户端存在资源缓存。如果If Modified Since与当前请求的资源的最后修改时间一致,则返回304,使用缓存资源。
这样,在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。常用的防止缓存的方法是在资源文件名后面加一个随机数,或者加时间戳。
分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败
ETag和If-None-Match
ETag:某种数据的 hash,包含在响应头中
If-None-Match:缓存文件的 ETag hash,包含在请求头中,如果与最近修改数据检查相同,服务器将返回 304 状态代码。如:
作用
Etag 主要为了解决 Last-Modified 无法解决的一些问题。
- 有些文件可能修改时间变了,但内容没有变化,这时候我们不希望客户端认为此文件被修改了,重新发起请求;
- 有些文件可能被频繁地修改,比如1s内修改了N次,而If-Modified-Since的检查粒度是秒级的,这种修改无法获取到。或者说UNIX记录MTIME只能精确到秒
- 有些服务器不能精确得到文件的最后修改时间
分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样)
Cache-Control
HTTP 1.1开始,使用Cache-Control头信息控制网页的缓存,它会覆盖其他设置,比如 Expires 和 Last-Modified。
- no-cache:这个值很容易让人误解,使人以为不会有缓存。官方的解释是:Forces caches to submit the request to the origin server for validation before releasing a cached copy。它是在强制浏览器使用资源副本前(不管本地副本是否过期),将请求提交源服务器进行验证。
- no-store:在任何条件下,缓存不应该存储关于客户端请求或服务器响应的任何内容。这一般是基于安全考虑的某些敏感响应才会使用。
- must-revalidate:缓存在使用之前必须验证是否过期,过期的资源不应该被使用。
- max-age=[单位:秒 seconds]:设置缓存最大的有效时间。与 Expires类似, 但它是一个相对时间,指在max-age秒以内缓存是有效的。如果和Expires同时存在,会覆盖Expires。
- s-maxage=[单位:秒 seconds]: 类似于 max-age, 但是它只用于公享缓存 (e.g., proxy)
- private:响应只能够作为私有的缓存(e.g., 在一个浏览器中),不能再用户间共享。
- public:响应会被缓存,并且在多用户间共享。正常情况, 如果要求 HTTP 认证,响应会自动设置为 private.
对于静态资源,我们期望是应该永远不过期的,可以给Expires设一个永远不会过期的时间,或者“Cache-Control: max-age = [超大值]”。当浏览器检查到本地有缓存时,不会再发起新的请求,而是直接走本地缓存:Status Code:200 OK (from disk cache)
而文件名后面应该带有时间戳或者版本号(如img_v1.png),当需要更新资源的时候,不是覆盖原文件,而是引用新文件(img_v2.png)。比如下图是一个静态资源的cache-control设置:
keep-alive
Connection:keep-alive 通过使用keep-alive机制使得http链接得到复用,即一段时间内,对同一域的请求可以不需要创建新的连接,而是使用之前的连接。避免了建立/释放链接的开销,以此提高性能。
其它
Expires、Cache-Control这几个http头可以作为meta标签发送到客户端,但是需要注意的是Http头中的设置优先级更高一些,例如: