HTTP缓存带来的“bug”--HTTP 协议 Cache-Control
问题描述
先说背景。网站是用PHP开发的,未用任何框架,代码结构也非常简单。运行于阿里云服务器,并采用其CDN来做分发。根据业务需求,有的页面会判断用户浏览器类型,依此来选择PC或者手机端内容。
在一次上线过程中,遇到比较诡异的问题:用PC和手机分别访问页面时,网页内容未根据浏览器类型来区分。而在开发环境,页面却能正常显示。仔细排查了代码,没有发现问题出在什么地方。而线上环境也不好调试,只能靠猜了。
解决过程
开发环境一切正常,说明代码出问题的可能性不大(当然后面发现还是代码的问题~)。而线上与开发环境的差别就在于多了一层CDN。会不会是CDN的问题?然而本人对CDN也是一知半解的,只知道是它会缓存源网站内容,并就近对用户进行内容分发,来加速访问。如果用户请求的内容CDN并未缓存,就会发生回源。对图片、css、js等静态资源,CDN缓存是理所应当的。但是对html内容,因为一般都是PHP动态生成的,会有一些业务逻辑,缓存这些内容就不太合适了。由于相关判断浏览器类型的代码是经过验证的,所以问题应该不在网站本身。考虑到上面CDN相关内容,我就在怀疑是不是CDN把html都缓存下来了,导致用户请求压根没到网站服务器。于是打开浏览器console,查看请求响应头,并把问题页的响应头和正常页面进行对比,果然发现了问题。正常页面每次刷新后,响应头里的Date字段都会改变;而问题页的Date字段一直没变化!也就是说问题页取到的内容一直都是CDN缓存。再次对比发现,正常页面还有Cache-Control相关内容,而问题页没有。于是推测CDN会根据响应头来决定是否会缓存内容。在问题页代码中增加缓存控制相关header后,果然正常了。然而问题又来了,正常页面的Cache-Control是哪里输出的呢?代码中并没有看到对应内容,估计是线上人为加了相关header,与开发环境代码不一致。
总结
一直以来对http响应头中的缓存控制相关内容都没有注意,遇到问题才发现它们的重要性。本次解决这个问题,主要是增加了以下header:
header('Pragma: no-cache');//兼容老版本协议 http1.0可能不识别Cache-Control
header('Cache-Control: no-store, no-cache, must-revalidate');//告诉浏览器/代理 不缓存内容
header("Expires: Mon, 26 Jul 1970 05:00:00 GMT"); //把过期时间设置为以往的时间,基本等同于Cache-Control:no-cache
页面加上三行代码后基本可保证其内容不被缓存。
阿里云CDN响应头中有几个关于缓存的字段需要注意:
X-Cache,值包含HIT时,表示命中缓存;MISS则表示未命中,需要回源
X-Swift-SaveTime 缓存保存时间
X-Swift-CacheTime 缓存时长
Age 当前资源已缓存的时间,达到X-Swift-CacheTime时缓存过期,会回源
想了解更多HTTP协议相关内容,请查看HTTP协议简介
HTTP缓存带来的“bug”--HTTP 协议 Cache-Control的更多相关文章
- host缓存,浏览器缓存---解决host缓存带来的伤
1.缓存 缓存,对应工程师来讲简直太熟悉了,太方便了,省略到资源或数据的获取方式,直接缓存到离用户访问最快的地方,也降低服务器的压力,比如: (1)静态文件获取 服务器->cdn->本地磁 ...
- ARP缓存表的构成ARP协议全面实战协议详解、攻击与防御
ARP缓存表的构成ARP协议全面实战协议详解.攻击与防御 1.4.3 ARP缓存表的构成 在局域网的任何一台主机中,都有一个ARP缓存表.该缓存表中保存中多个ARP条目.每个ARP条目都是由一个IP ...
- 缓存系列之一:buffer、cache与浏览器缓存
缓存系列之一:buffer.cache与浏览器缓存 一:缓存是为了调节速度不一致的两个或多个不同的物质的速度,在中间对速度较快的一方起到一个加速访问速度较慢的一方的作用,比如CPU的一级.二级缓存是保 ...
- 服务升级带来的Bug,BAT也不能幸免
这是标题党,关于阿里的,BT躺枪了. 为什么淘宝上找不到"亲淘"了? 好吧,我今天遇到了一个Bug: 立即更新,然后你看到了: 才发现亲淘不能使用了. 看官方页面: 提示:2016 ...
- 由于未清除缓存引发的bug
在写页面的时候,首先引入了本地react.js和react-dom.js 16版本(cjs)的文件,出现如下错误 发现bug后,将本地的react.js和react-dom.js文件改成16.2(um ...
- 浏览器缓存引起的bug总结
缓存原理 浏览器缓存分为强缓存和协商缓存 先检查是否过期,没有过期直接使用本地缓存.如果过期,查看是否使用协商缓存 协商缓存流程: 后端返回headers: ETag: W/"1e3-175 ...
- 网站 cache control 最佳实践
推荐阅读: 2020年软件开发趋势 高并发案例 - 库存超发问题 负载均衡的分类及算法 异地多活架构 Postman 的替代品来了 有时,当第二次访问网站时,看起来比较怪,样式不正常. 通常,是因为 ...
- [转]ASP.NET Core: Static Files cache control using HTTP Headers
本文转自:https://www.ryadel.com/en/asp-net-core-static-files-cache-control-using-http-headers/ Every sea ...
- MemCache分布式缓存的一个bug
Memcached分布式缓存策略不是由服务器端至支持的,多台服务器之间并不知道彼此的存在.分布式的实现是由客户端代码(Memcached.ClientLibrary)通过缓存key-server映射来 ...
随机推荐
- No bean named 'sessionFactory' is defined
1.错误描述 严重:Servlet service() for servlet default threw exception . org.springframework.beans.factory. ...
- Linux显示计算次数的结果
Linux显示计算次数的结果 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ free -c free:选项需要一个参数 -- c Usage: free [o ...
- E: 未发现软件包 install_flash_player_11_linux.x86_64.tar.gz
1 错误描述 youhaidong@youhaidong:~$ sudo apt-get install install_flash_player_11_linux.x86_64.tar.gz 正在读 ...
- eclipse 修改默认的author
1. 在eclipse.ini中添加 -vmargs -Duser.name={author name} 记得一定要在-vmargs之后,否则无效. 2. 设置eclipse参数 windows--& ...
- 命令行工具osql.exe使用
目标: 快速在21个库修改Test表的某条记录,这几个库都分别在不同的服务器上. 通常会想到,到每个库都执行一下语句不就好了吗?这个数据库切换来切换去,挺麻烦了,通过命令行工具osql.exe就可以快 ...
- order调用mdp
Java代码 else { crmMessageService[A1] .applyAsync(crmMdpRequest); } public v ...
- C#图解教程 第十九章 LINQ
LINQ 什么是LINQLINQ提供程序 匿名类型 方法语法和查询语法查询变量查询表达式的结构 from子句join子句什么是联结查询主体中的from-let-where片段 from子句let子句w ...
- Centos7.2 搭建Lamp服务器以及迁移WordPress个人博客详细过程
其实自己的博客搭了有段时间了,但是由于自己不太确定是不是一定要用wd的框架,以及实验室公网服务器的不稳定,就一直荒废着. 今天偶然间看到了腾讯云对于学生的优惠活动,毕业之前每月只要8元的云服务器(就算 ...
- CSS3动画--过渡效果
CSS3动画--过渡效果 transition 设置四个过渡属性 transition-property 过渡的名称 tr ...
- 描述Spring Web MVC的工作流程
Spring Web MVC的共工作流程如下: 1.浏览器发出Spring mvc请求,请求给前端控制器 DispatcherServlet处理. 2.控制器通过HandlerMapping维护的请求 ...