Open msforest opened 6 years ago
新到一个工作环境,被要求解决浏览器缓存加载的问题。拿到一个新项目,包含各种资源文件:html/css/js/python/node,之前是只需要做前端,现在是前后都得干,有点不习惯,先熟悉一波文件目录结构,还是有规律可寻的。
问题:本地代码部署到线上,其他人使用浏览器打开没有加载最新部署的资源,还是使用浏览器缓存的文件,需要通过f12 + disabled cache或ctrl+f5来强制刷新加载。
12 + disabled cache
ctrl+f5
过程:一般想要重新加载资源文件或请求API,是在后面加个时间戳来更改请求地址以实现浏览器缓存不存在同样的请求地址,这种解决方案我只是看看,真的做起来不太现实,文件这么多,API又何其多;就剩下以前想尝试但又没机会尝试的方法--通过配置HTTP header来解决浏览器缓存问题。
环境:系统ubuntu16.04 / 服务器Apache2.4.18 几个请求头的知识点:
Etag: 根据文件内容生成的一个值,比根据缓存时间判断更划算 Expires: 指定了一个日期/时间, 在这个日期/时间之后,HTTP响应被认为是过时的;需和Last-Modified结合使用。用于控制请求文件的有效时间,当请求数据在有效期内时客户端浏览器从缓存请求数据而不是服务器端.当缓存中数据失效或过期,才决定从服务器更新数据。HTTP 1.0 版本 Cache-Control: 用于在http 请求和响应中通过指定指令来实现缓存机制。HTTP 1.1版本,资源在本地缓存多少秒。 If-None-Match: 值为上一次响应头返回的etag值,作为请求头发送 Last-Modified: 响应头返回的文件最后修改时间 If-Modified-Since: 值为上一次响应头返回的修改时间,作为请求头发送
更多请参考mdn
然后就是更改Apache的配置信息,找到Apache的安装目录:
//https://stackoverflow.com/questions/29127144/cant-cache-resource-when-having-both-gzip-and-etag <IfModule mod_headers.c> Header unset ETag </IfModule> FileETag None
表示不发送etag响应头
从Apache2.4.0之后,由于Etag默认被加上gzip后缀,导致请求不会发送304响应码
https://httpd.apache.org/docs/trunk/mod/mod_deflate.html#deflatealteretag
发现了问题就去解决问题,不去解决就是耍无赖,毕竟响应码还是很重要的一个信息
开启mod_header.c的命令:sudo a2enmod headers
sudo a2enmod headers
先了解etag的原理
https://httpd.apache.org/docs/2.4/zh-cn/mod/core.html#fileetag
简而言之,etag由文件在系统的索引节点+文件最后修改的时间+文件大小组成的 修改如下
http://httpd.apache.org/docs/current/mod/mod_headers.html
<IfModule mod_expires.c> ExpiresActive On ExpiresDefault A1000 </IfModule>
M means that the file's last modification time should be used as the base time, and A means the client's access time should be used
https://httpd.apache.org/docs/trunk/mod/mod_expires.html
sudo a2enmod expires执行该命令启用模块,然后重启服务
sudo a2enmod expires
以下仅供参考:
ExpiresActive On ExpiresDefault A2592000 # GIF有效期为1个月 ExpiresByType image/gif A2592000 # HTML文档的有效期是最后修改时刻后的一星期 ExpiresByType text/html M604800 #以下的含义类似 ExpiresByType text/css "now plus 2 months" ExpiresByType text/js "now plus 2 days" ExpiresByType image/jpeg "access plus 2 months" ExpiresByType image/bmp "access plus 2 months" ExpiresByType image/x-icon "access plus 2 months" ExpiresByType image/png "access plus 2 months"
问题发现(未解决): 经过本地和线上测试发现:客户端获取最新资源的措施,服务端已设置请求头ETAG来判断是否使用最新文件还是使用浏览器缓存文件,且浏览器已生效,IE和Firefox是没有问题的,chrome现在的情况是有时生效有时不生效,不生效是因为chrome请求头会报如下错误信息 综合网上解决方案,发生错误的原因:
猜测有可能是网络问题,因为本地测试一切正常,只有线上才会出现改现象,而且线上服务器不再国内
ab -n 100 -c 100 http://127.0.0.1:8080/ detail
ab -n 100 -c 100 http://127.0.0.1:8080/
强缓存和协商缓存
新到一个工作环境,被要求解决浏览器缓存加载的问题。拿到一个新项目,包含各种资源文件:html/css/js/python/node,之前是只需要做前端,现在是前后都得干,有点不习惯,先熟悉一波文件目录结构,还是有规律可寻的。
问题:本地代码部署到线上,其他人使用浏览器打开没有加载最新部署的资源,还是使用浏览器缓存的文件,需要通过f
12 + disabled cache
或ctrl+f5
来强制刷新加载。过程:一般想要重新加载资源文件或请求API,是在后面加个时间戳来更改请求地址以实现浏览器缓存不存在同样的请求地址,这种解决方案我只是看看,真的做起来不太现实,文件这么多,API又何其多;就剩下以前想尝试但又没机会尝试的方法--通过配置HTTP header来解决浏览器缓存问题。
环境:系统ubuntu16.04 / 服务器Apache2.4.18 几个请求头的知识点:
更多请参考mdn
然后就是更改Apache的配置信息,找到Apache的安装目录:
表示不发送etag响应头
从Apache2.4.0之后,由于Etag默认被加上gzip后缀,导致请求不会发送304响应码
发现了问题就去解决问题,不去解决就是耍无赖,毕竟响应码还是很重要的一个信息
开启mod_header.c的命令:
sudo a2enmod headers
修改etag的生成规则
先了解etag的原理
简而言之,etag由文件在系统的索引节点+文件最后修改的时间+文件大小组成的 修改如下
设置expires的值
M means that the file's last modification time should be used as the base time, and A means the client's access time should be used
sudo a2enmod expires
执行该命令启用模块,然后重启服务以下仅供参考:
问题发现(未解决): 经过本地和线上测试发现:客户端获取最新资源的措施,服务端已设置请求头ETAG来判断是否使用最新文件还是使用浏览器缓存文件,且浏览器已生效,IE和Firefox是没有问题的,chrome现在的情况是有时生效有时不生效,不生效是因为chrome请求头会报如下错误信息 综合网上解决方案,发生错误的原因:
猜测有可能是网络问题,因为本地测试一切正常,只有线上才会出现改现象,而且线上服务器不再国内