手摸手教你解决重定向缓存问题

手摸手教你解决重定向缓存问题css

问题产生:

测试粑粑:测试环境已经搭好了,前端打个包吧!
weber:好嘞!快速输入命令:npm run build:stagging
三分钟后……
测试粑粑:是否是打错包了?怎么还没变?
weber:刷新下页面试试!
测试粑粑:没用鸭~
weber:蛤~清理下浏览器缓存!
测试粑粑:出来了,**牛皮鸭!!!html

问题到这里,我陷入了沉思,咋回事呢,若是每次发布须要用户手动清除浏览器缓存,这无疑是一个巨大的bug?因而开始列出了问题排查清单:
一、刷新页面从新进行了doc【index.html】请求,无效;而清理浏览器缓存缺生效了,说明浏览器缓存了文件致使刷新请求时仍是以前的文件。
二、webpack打包时,outputjscss加上了hash,那jscss应该就不会缓存。前端

开始排查

1、检查了webpack打包配置:java

module.exports = {
  context : path.join(__dirname,'src'),
  entry:{
    main: './index.js',
    vender:['./jquery.js','./test.js']
  },
  module:{
    rules:[{
      test:/\.css$/,
      use: extractTextPlugin.extract({
        fallback:'style-loader',
        use:'css-loader'
      })
    }]
  },
  output:{
    path:path.join(__dirname, '/dist/js'),
    filename: 'bundle.[name].[hash].js',
  },
  plugins:[
    new extractTextPlugin('../css/bundle.[name].[hash].css')
  ]
}
复制代码

发现webpack打包没有问题。jquery

2、打包后的文件也没有问题。

3、打包后生成的index.html文件引入。

3、查看network请求才恍然大悟:

index.html304请求,那说明index.html被缓存了。webpack

解决问题

开始寻找解决办法,方法有不少,有前端配置的,也有后端配置的。ios

考虑到webpack打包生成的html只是做为引入jscss的容器,若只是不缓存html文件,代价其实很小。选择以下方法:nginx

一、在html head头部添加不缓存html配置:web

注:metatml语言head区的一个辅助性标签,其中的http-equiv字段定义了服务器和用户代理的一些行为。在以前的规范中,metahttp-equiv字段中有如下值与http header缓存相关的字段功能相似面试

<head>
  <meta http-equiv="pragma" content="no-cache">
  <meta http-equiv="cache-control" content="no-cache">
  <meta http-equiv="expires" content="0">
</head>
复制代码

若采用这种方式,请在public文件加下的index.html配置。

二、修改nginx.conf,增长add_header Cache-Control 'no-cache, no-store, must-revalidate'不缓存html配置:

server {
  listen       80;
  server_name  localhost;

  root        /usr/share/nginx/html;
  index       index.html;

  location ~* \.(gif|jpg|jpeg|png|css|js|ico|eot|otf|fon|font|ttf|ttc|woff|woff2)$ {
      expires 1M;
      add_header Cache-Control "public";
  }

  location / {
      add_header Cache-Control 'no-cache, no-store, must-revalidate';
  }

  error_page  404              /index.html;
}
复制代码

其实这两个配置都是在请求head加上不缓存html的配置,一个在前端,一个在运维。翻阅w3c文档发现,但如今w3c的规范字段中这些值已经被移除,一个很好的理由是:

Putting caching instructions into meta tags is not a good idea, because although browsers may read them, proxies won't. For that reason, they are invalid and you should send caching instructions as real HTTP headers.

综合以后仍是第二种方案较为完善。

bug再现:

weber:此次修改了nginx配置,此次打包应该不会出现上次的缓存问题了,不用手动清楚浏览器缓存了!
测试粑粑:牛皮鸭,我试试~
weber:(自信的小表情,期待的小红手)~
测试粑粑:仍是有问题鸭!仍是没更新过来!
weber:你是直接请求是吧?有没有刷新页面?
测试粑粑:没有,直接请求的~
weber:好了,我知道了!

问题到这里,又出现了bug。若是直接请求网址,是会请求到最新的html文件,可是还会存在用户不刷新直接请求的状况。

理清思路:

其实到这一步问题已经很清晰了,从新理一遍webpack打包过程、浏览器缓存策略,问题就很容易解决了。
1、webpack打包:

public/index.html:文件是一个会被 html-webpack-plugin 处理的模板。在构建过程当中,资源连接会被自动注入。另外,Vue CLI 也会自动注入 resource hint (preload/prefetch、manifest 和图标连接 (当用到 PWA 插件时) 以及构建过程当中处理的 JavaScriptCSS 文件的资源连接。ouput里面的文件都会inject

2、HTTP重定向:

服务器的nginx配置以下:

倘若输入:https://example.comhttps://example.com/a都会定位到root下的index.html文件,也会触发请求html文件。

3、浏览器缓存:

再次查看增长了不缓存html文件,请求状态变成了200

所以,在不刷新浏览器的状况下请求,html是没有被请求的,仍然是第一次输入网址请求回来的html文件,里面的jscss也是以前的,因此浏览器不会再去请求jscss文件。解决办法:

axios请求加上版本号,若是版本号对应不上,则返回code,让前端去与用户交互是否已经更新了,须要刷新页面。

相关文章
相关标签/搜索