缓存在web环境各个环节都有实现,有CPU缓存、文件缓存、程序的Opcode缓存(APC,eAccelerator)、内存缓存(Memcached,Redis)、代理服务器(Nginx,Squid)、数据库的查询缓存、基于HTTP的客户端缓存。其中HTTP缓存是离用户最近的缓存,访问最快,合理使用可以加快数据加载速度、减少服务器的开销。
HTTP缓存通过设置一些头加以控制,有一部分是控制要不要缓存、怎么缓存以及缓存多久的,还有一部分是决定缓存过期以后怎么处理的。下面只列出最主要的:
缓存控制
Cache-Control
public:公共,可以被客户端和代理服务器(如Nginx、Squid)缓存
private:私有,只能被当前客户端缓存
no-store:不缓存,客户端不维护缓存
no-cache:并不是不缓存,但是每次都会请求服务器,可以配合ETag和Last-Modified来避免响应重复的内容,适用于需要显示最新内容的场景
max-stale:客户端可以设置它来使用已经过期的缓存,单位为秒,这个时间是已经过期了多少秒的意思
must-revalidate:因为客户端可以设置max-stale来使用已经过期的缓存,服务器可以设置它来强制客户端不允许使用过期的缓存,必须重新请求服务器
Pragma:相比Cache-Control,它是不支持响应头的,通常是为了向后兼容HTTP/1.0
缓存时间
max-age:距离请求发起的时间的秒数,Cache-Control指令之一
Expires:过期时间(GMT格式),和max-age类似,但是Expires受客户端时间影响,是HTTP/1.0的标准,max-age是它的改良版,优先级为:max-age -> Expires
缓存校验(缓存过期后通过比较来检查是否继续使用)
Last-Modified:服务端在响应头里面设置此项来告知客户端资源的修改时间(GMT格式),客户端会在下次请求时自动加上If-Modified-Since: <last_modified_value>,服务端以此来比对缓存是否有更新
ETag(Entity Tags):依赖Last-Modified来检查缓存有缺陷,比如文件的修改时间变了但是内容没有变,又比如它只能精确到秒,而ETag是比对内容,可以理解为md5值,服务端响应ETag后客户端会在下次请求时自动带上If-None-Match: <etag_value>。ETag比Last-Modified开销大,如果可以用Last-Modified尽量用Last-Modified
注意private的应用场景,比如个人中心的url是/userinfo.php,所有人的url都是相同的,这个时候如果用了public走了代理缓存,会导致所有人共享一个缓存,所以这种时候需要使用private。
实例
缓存一分钟,一分钟内直接读取本地缓存,一分钟后重新请求服务器:
Cache-Control: public, max-age=60, must-revalidate
上面这种方式一旦缓存过期就会重新请求服务器返回最新的内容,如果内容并没有变化,那不是白传了?有没有办法在缓存过期以后判断一下如果内容没有改变则继续用本地的缓存呢?很简单!ETag可以帮到你,有效期内直接读取本地缓存,过期后跟服务器比对ETag,相同则服务器会返回304表示缓存还可以继续用,而不返回实际内容,节约了时间和带宽。
HTTP缓存通过设置一些头加以控制,有一部分是控制要不要缓存、怎么缓存以及缓存多久的,还有一部分是决定缓存过期以后怎么处理的。下面只列出最主要的:
缓存控制
Cache-Control
public:公共,可以被客户端和代理服务器(如Nginx、Squid)缓存
private:私有,只能被当前客户端缓存
no-store:不缓存,客户端不维护缓存
no-cache:并不是不缓存,但是每次都会请求服务器,可以配合ETag和Last-Modified来避免响应重复的内容,适用于需要显示最新内容的场景
max-stale:客户端可以设置它来使用已经过期的缓存,单位为秒,这个时间是已经过期了多少秒的意思
must-revalidate:因为客户端可以设置max-stale来使用已经过期的缓存,服务器可以设置它来强制客户端不允许使用过期的缓存,必须重新请求服务器
Pragma:相比Cache-Control,它是不支持响应头的,通常是为了向后兼容HTTP/1.0
缓存时间
max-age:距离请求发起的时间的秒数,Cache-Control指令之一
Expires:过期时间(GMT格式),和max-age类似,但是Expires受客户端时间影响,是HTTP/1.0的标准,max-age是它的改良版,优先级为:max-age -> Expires
缓存校验(缓存过期后通过比较来检查是否继续使用)
Last-Modified:服务端在响应头里面设置此项来告知客户端资源的修改时间(GMT格式),客户端会在下次请求时自动加上If-Modified-Since: <last_modified_value>,服务端以此来比对缓存是否有更新
ETag(Entity Tags):依赖Last-Modified来检查缓存有缺陷,比如文件的修改时间变了但是内容没有变,又比如它只能精确到秒,而ETag是比对内容,可以理解为md5值,服务端响应ETag后客户端会在下次请求时自动带上If-None-Match: <etag_value>。ETag比Last-Modified开销大,如果可以用Last-Modified尽量用Last-Modified
注意private的应用场景,比如个人中心的url是/userinfo.php,所有人的url都是相同的,这个时候如果用了public走了代理缓存,会导致所有人共享一个缓存,所以这种时候需要使用private。
实例
缓存一分钟,一分钟内直接读取本地缓存,一分钟后重新请求服务器:
Cache-Control: public, max-age=60, must-revalidate
上面这种方式一旦缓存过期就会重新请求服务器返回最新的内容,如果内容并没有变化,那不是白传了?有没有办法在缓存过期以后判断一下如果内容没有改变则继续用本地的缓存呢?很简单!ETag可以帮到你,有效期内直接读取本地缓存,过期后跟服务器比对ETag,相同则服务器会返回304表示缓存还可以继续用,而不返回实际内容,节约了时间和带宽。
我们凭借多年的网站建设经验,坚持以"帮助中小企业实现网络营销化"为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线: 13812912584 / 18013771099,我们会详细为你一一解答你心中的疑难。项目经理在线
请立即点击咨询我们或拨打咨询热线: 13812912584 / 18013771099,我们会详细为你一一解答你心中的疑难。项目经理在线