微信公众号H5页面缓存问题(微信缓存了 index.html 入口)

做微信公众号和调试手机页面的时候,避免不了页面要跳转到微信浏览器打开,调试阶段,android版微信浏览器一直都默认缓存html静态资源,每次静态资源变化甚至新内容发布的时候在微信浏览器上都极有可能不能更新,很多时候要清理微信缓存才能看到效果,很是烦人。部分客户装了QQ浏览器,微信实际调用的是QQ浏览器,有时候甚至光清理微信缓存都无效,QQ浏览器的缓存也要清。

经过一番探索微信浏览器确实是在webview的上层做的缓存:就是如果请求过了这个地址,就会存在本地,之后不取线上了。

解决方案是在调试阶段或者频繁更新的页面加入以下头信息

因为是 HTML 页面,可以于 HEAD 标签内直接添加 META 标签:

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
 
<meta http-equiv="Pragma" content="no-cache" />
 
<meta http-equiv="Expires" content="0" />
 
这样微信浏览器对这个页面将会一直上线拉取了。

但是微信浏览器是把index.html入口文件缓存了,这时候要前端和服务端一起处理。

vue.config.js 前端需要把打包文件 生成的js css加上时间戳或者随机,确保每次打包都会更新。在output项配置,并且把生成的index.html进行压缩,去除空格,换行和注释 减小文件体积

const webpack = require('webpack');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const productionGzipExtensions = ['html', 'js', 'css'];
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 判断是否为二级目录部署
const alpha = process.env.NODE_ENV === 'production' && process.env.VUE_APP_DIR;
const Timestamp = new Date().getTime();
module.exports = {
  publicPath: alpha ? `/${process.env.VUE_APP_DIR}/` : '/',
  // px转rem的配置(postcss-plugin-px2rem插件)
  lintOnSave: true,
  productionSourceMap: false,
  chainWebpack(config) {
    config.entry('main').add('babel-polyfill'); // main是入口js文件
    // it can improve the speed of the first screen, it is recommended to turn on preload
    config.plugin('preload').tap(() => [
      {
        rel: 'preload',
        // to ignore runtime.js
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
        include: 'initial',
      },
    ]);
  },
  configureWebpack: {
    plugins: [
      // Ignore all locale files of moment.js
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
      // 配置compression-webpack-plugin压缩
      new CompressionWebpackPlugin({
        algorithm: 'gzip',
        test: new RegExp(`\\.(${productionGzipExtensions.join('|')})$`),
        threshold: 10240,
        minRatio: 0.8,
      }),
      new webpack.optimize.LimitChunkCountPlugin({
        maxChunks: 5,
        minChunkSize: 100,
      }),
      // 配置html的文件
      new HtmlWebpackPlugin({
        template: './public/index.html', // 模板地址
        // title: '自定义title',
        url: process.env.VUE_APP_DIR ? `/${process.env.VUE_APP_DIR}/` : '', // 需要这里传参DIR配置文件里面(二级目录)
        minify: { // 压缩HTML文件
          removeAttributeQuotes: true, // 移除属性的引号
          removeComments: true, // 移除HTML中的注释
          collapseWhitespace: true, // 删除空白符与换行符
          minifyCSS: true, // 压缩内联css
        },
        inject: true, // true 或body 默认值,script标签位于html文件的 body 底部; head script 标签位于 head 标签内
        // hash: true, // 引入 js 文件后面紧跟一个独特的 hash 值
        // filename: 'index-[hash].html', // 输出带hash 值的文件名
      }),
    ],
    output: {
      // 输出重构  打包编译后的 文件名称  【模块名称.版本号.时间戳】
      // filename: `js/[name].[chunkhash].${Timestamp}.js`,
      // chunkFilename: `js/[name].[chunkhash].${Timestamp}.js`,
      filename: `js/[name].${Timestamp}.js`,
      chunkFilename: `js/[name].${Timestamp}.js`,
    },
  },
  css: {
    loaderOptions: {
      postcss: {
        plugins: [
          require('postcss-plugin-px2rem')({
            rootValue: 50, // 换算基数, 默认100  ,这样的话把根标签的字体规定为1rem为50px,这样就可以从设计稿上量出多少个px直接在代码中写多上px了。
            // unitPrecision: 5, //允许REM单位增长到的十进制数字。
            // propWhiteList: [],  //默认值是一个空数组,这意味着禁用白名单并启用所有属性。
            // propBlackList: [], //黑名单
            exclude: /(node_module)/, // 默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
            selectorBlackList: [], // 要忽略并保留为px的选择器
            // ignoreIdentifier: false,  //(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
            // replace: true, // (布尔值)替换包含REM的规则,而不是添加回退。
            mediaQuery: false, // (布尔值)允许在媒体查询中转换px。
            minPixelValue: 0, // 设置要替换的最小像素值(3px会被转rem)。 默认 0
          }),
        ],
      },
    },
  },
  // devServer: {
  //   proxy: {
  //     '/epidemic-report-api': {
  //       target: 'https://bbjh.org.cn',
  //       changeOrigin: true,
  //       ws: true,
  //     },
  //   },
  // },
};

服务器nginx配置,默认缓存了其他文件,对index.html拦截实现强制不缓存。每次都要请求服务器,我这个index.html使用html-webpack-plugin插件压缩之后体积从1.4k缩小到了,不到1k。目的减少服务器带宽。

server { 
        listen       80; 
        #add_header Access-Control-Allow-Origin *; 
        #add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; 
        #add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; 
		#add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy- revalidate, max-age=0'; 
        server_name  *******.com; 
        
        location ~* \.(html)$ { //拦截index.html强制不缓存
                add_header  Cache-Control  "private, no-store, no-cache, must-revalidate, proxy-revalidate"; 
            	root   /opt/static_projects/******; 
        } 
        
        location / { 
            root   /opt/static_projects/******; 
            try_files $uri $uri/ @router; 
            index  index.html; 
        } 
        location @router { 
            rewrite ^.*$ /index.html last; 
        } 
     
} 

注意:在index.html文件里面使用的 打包时会提示找到报错,替换为

验证:用微信开发者工具查看入口文件的更新时间

A标签锚点跳转不改变路由地址

奥利给

原因,我们经常需要用a标签来做锚点跳转,但是尴尬的就是跳转后地址栏的url会改变,起初我也没注意。(讲真,这个有时候又好处,有时候有坏处。坏处就是改变了路由,就很不优雅,好处是如果用户把这个链接分享出去他可以跳转到之前用户停留的锚点)

为什么要用a标签跳转啊,我用别的不行吗?当然可以,但是我们得考虑如果js不运行了,起码还有原始的锚点跳转做保证吧。

原理就是js查找a标签指向的锚点,但是我们不可能一个一个写吧,不然很不优雅。所以我们就封装寻找所有a标签,再判断指向是否含有#号,如果有则的添加点击事件。调用scroll函数滚到指向的元素。但是我们发现地址栏url还是改变了,那证明a标签的跳转还是存在,那我们就把a标签的默认点击事件去除掉。

完美,优雅。

精益求精的小伙伴还可以加一个时间函数来缓慢移动。

这样我们只需要在页面中引入改js即可,且不用注意什么,正常写我们的前端代码即可。

(function(){
	var allJump=[];
	var allA=document.querySelectorAll("a");// 获取所有a标签
	allA.forEach((ele,index)=>{
		// console.log(index);
		// console.log(ele.href);
		if(ele.href.search("#")>12){
			allJump.push(ele);// 判断a标签是否含有#	
		}
	})
	// console.log(allJump);
	allJump.forEach((ele)=>{
		ele.addEventListener("click",(e)=>{
			// 首先解析出href
			e.preventDefault();// 这个非常关键
			var jumpTarget=ele.href.split("#")[1]
			if(jumpTarget){
				// console.log(123);
				var targaetEle=document.querySelector("#"+jumpTarget);
				h=targaetEle.offsetTop;
				window.scrollTo(0,h);
				// console.log(jumpTarget);
			}else{
				window.scrollTo(0,0);
			}
		});			
		// return false;
	})
}).call()

本站内容来自用户投稿,如果侵犯了您的权利,请与我们联系删除。联系邮箱:835971066@qq.com

本文链接:http://news.xiuzhanwang.com/post/2761.html

友情链接: