问题描述

先说背景。网站是用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. HighCharts之2D圆环图

    HighCharts之2D圆环图 1.实例源码 Donut.html: <!DOCTYPE html> <html> <head> <meta charset ...

  2. 芝麻HTTP:Scrapy-Splash的安装

    Scrapy-Splash是一个Scrapy中支持JavaScript渲染的工具,本节来介绍它的安装方式. Scrapy-Splash的安装分为两部分.一个是Splash服务的安装,具体是通过Dock ...

  3. 在.Net Core中使用MongoDB的入门教程(二)

    在上一篇文章中,讲到了MongoDB在导入驱动.MongoDB的连接,数据的插入等. 在.Net Core中使用MongoDB的入门教程(一) 本篇文章将接着上篇文章进行介绍MongoDB在.Net ...

  4. 利用scrapy模拟登录知乎

    闲来无事,写一个模拟登录知乎的小demo. 分析网页发现:登录需要的手机号,密码,_xsrf参数,验证码 实现思路: 1.获取验证码 2.获取_xsrf 参数 3.携带参数,请求登录 验证码url : ...

  5. Keras官方中文文档:keras后端Backend

    所属分类:Keras Keras后端 什么是"后端" Keras是一个模型级的库,提供了快速构建深度学习网络的模块.Keras并不处理如张量乘法.卷积等底层操作.这些操作依赖于某种 ...

  6. css - 移动端reset汇总与注释

    1.解决移动端触摸a元素,会有蓝色阴影 正常状态: 点击时状态: a{ outline:none; -webkit-tap-highlight-color: rgba(,,,); } -webkit- ...

  7. Redis之String

    一.Redis之String简介 1. String是redis最基本的数据类型,一个key对应一个value. 2. String是二进制安全的,可以包含任何数据,例如图片或序列化的对象. 3. S ...

  8. Micropython TurnipBit 电子时钟 青少年编程入门

    电子时钟是一个很常用但是制作非常简单的小玩具了,对于Micropython初学者来说,制作一个电子时钟是非常简单又容易检验自己学习成果的实验了.TurnipBit相比于其他开发板,制作电子时钟就更加简 ...

  9. 浏览器中直接是使用react系列包开发,非打包方式。

    直接上代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  10. MongoDB 桌面管理器MongoVUE

    MongoVUE是一个桌面GUI工具,专用于Windows平台,它有一个简洁.清爽的界面,它的基本功能是免费的.它可以以文本视图.树视图.表格视图来显示MongoDB的数据.还可以保持查询的结果供以后 ...