问题描述

先说背景。网站是用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的更多相关文章

  1. host缓存,浏览器缓存---解决host缓存带来的伤

    1.缓存 缓存,对应工程师来讲简直太熟悉了,太方便了,省略到资源或数据的获取方式,直接缓存到离用户访问最快的地方,也降低服务器的压力,比如: (1)静态文件获取 服务器->cdn->本地磁 ...

  2. ARP缓存表的构成ARP协议全面实战协议详解、攻击与防御

    ARP缓存表的构成ARP协议全面实战协议详解.攻击与防御 1.4.3  ARP缓存表的构成 在局域网的任何一台主机中,都有一个ARP缓存表.该缓存表中保存中多个ARP条目.每个ARP条目都是由一个IP ...

  3. 缓存系列之一:buffer、cache与浏览器缓存

    缓存系列之一:buffer.cache与浏览器缓存 一:缓存是为了调节速度不一致的两个或多个不同的物质的速度,在中间对速度较快的一方起到一个加速访问速度较慢的一方的作用,比如CPU的一级.二级缓存是保 ...

  4. 服务升级带来的Bug,BAT也不能幸免

    这是标题党,关于阿里的,BT躺枪了. 为什么淘宝上找不到"亲淘"了? 好吧,我今天遇到了一个Bug: 立即更新,然后你看到了: 才发现亲淘不能使用了. 看官方页面: 提示:2016 ...

  5. 由于未清除缓存引发的bug

    在写页面的时候,首先引入了本地react.js和react-dom.js 16版本(cjs)的文件,出现如下错误 发现bug后,将本地的react.js和react-dom.js文件改成16.2(um ...

  6. 浏览器缓存引起的bug总结

    缓存原理 浏览器缓存分为强缓存和协商缓存 先检查是否过期,没有过期直接使用本地缓存.如果过期,查看是否使用协商缓存 协商缓存流程: 后端返回headers: ETag: W/"1e3-175 ...

  7. 网站 cache control 最佳实践

    推荐阅读: 2020年软件开发趋势 高并发案例 - 库存超发问题 负载均衡的分类及算法 异地多活架构 Postman 的替代品来了 有时,当第二次访问网站时,看起来比较怪,样式不正常. 通常,是因为 ...

  8. [转]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 ...

  9. MemCache分布式缓存的一个bug

    Memcached分布式缓存策略不是由服务器端至支持的,多台服务器之间并不知道彼此的存在.分布式的实现是由客户端代码(Memcached.ClientLibrary)通过缓存key-server映射来 ...

随机推荐

  1. MyEclipse中修改项目运行地址栏中项目名称

    MyEclipse中修改项目运行地址栏中项目名称 1.如果出现从SVN上检出的项目名称跟运行地址栏中的项目名称不一致, 可以通过以下步骤进行修改 项目鼠标右键,单击"Properties&q ...

  2. DirectShow中写push模式的source filter流程 + 源代码(内附详细注释)

    虽然网上已有很多关于DirectShow写source filter的资料,不过很多刚开始学的朋友总说讲的不是很清楚(可能其中作者省略了许多他认为简 单的过程),读者总希望看到象第一步怎么做,第二步怎 ...

  3. springMVC web项目 对访问数据库的用户名密码进行加密解密

    在使用springMVC开发web项目中,数据库的用户名,密码一般都是配置在.properties文件中 然后在通过.xml配置文件引入.properties的变量,例如 在config.proper ...

  4. unity案例入门(二)(坦克大战)

    1. 案例简述 这个案例实现一个简单的坦克对战游戏,两个玩家在一个地图上PK. 2. 控制坦克移动 与案例一中小球的移动方式不同,坦克在横向上不能是平移,因此横向按键控制的应该是坦克旋转. publi ...

  5. 深度学习框架: Keras官方中文版文档正式发布

    今年 1 月 12 日,Keras 作者 François Chollet‏ 在推特上表示因为中文读者的广泛关注,他已经在 GitHub 上展开了一个 Keras 中文文档项目.而昨日,Françoi ...

  6. as版本切换导致项目损坏,无法启动。环境依赖混乱

    以下方法都不管用, 新建一个项目setting的 把main拷过去就行了!!!! Error:(5, 0) Gradle DSL method not found: 'google()'Possibl ...

  7. 自言自语WEB前端面试题(一)

    刚刚得到通知,明天可能要放半天假,开心的像个200斤的傻子 我怕真是个傻子,是后天 今天的我是依旧痛经的我 于是我又来写博客了 原来,博客竟是痛经良药 接下来请看题,此题,0难度,基本不需要动脑子 J ...

  8. 【noip模拟】tree

    000 ms        Memory Limit: 128 MB [吐槽] 点分治点分治点分治 嗯..场上思考树状数组的时候好像傻掉了..反正就是挂了就是了.. [题解] 首先如果没有环的话就是一 ...

  9. 访问不了firefox附加组件页面怎么办

    最近重新使用火狐浏览器的时候发现访问不了firefox附加组件页面了,一直是一个空白的页面,估计是被墙的原因,于是网上查了查,说是修改hosts即可,我修改后就可以正常访问了.现在分享出来: 在hos ...

  10. python web开发-flask中response,cookies,session对象使用详解

    Response响应对象: 当一个web请求被服务器处理完后,会返回用户请求的响应,这时候就要用到响应对象,根据响应给用户的形式不同,响应对象有以下几种处理方式 如果返回的是一个合法的响应对象,它会从 ...