微信网页开发踩坑记

1,052 阅读5分钟

最近参与了公司的微信公众号商城站点的开发与上线过程,遇到一些印象比较深刻的坑,经过多方查找,最后终于一一解决了,写个文章总结下。主要有三个坑:

  1. 微信公众号网页二次分享问题
  2. 复制粘贴板安卓和ios兼容性问题
  3. 调用window.history.go(-1)时回退页面刷新问题

不想听我讲废话的以及探究过程的,提前写明症状及处理方法,不浪费大家的时间。

  1. 对于第一个二次分享问题,经过多方查找,发现经过微信公众号网页分享出去的页面,微信会自动加上from=xx&isappinstalled=0参数,点击分享链接进来,调用wx.config进行配置时,即使有正确的配置参数signature,微信也会报 invalid signature。起初怀疑是url多了分享的参数导致的问题,后来翻了下微信jssdk的开发文档,对于错误原因,可以查看微信公众平台开发文档附录五,有这样一段话:

    确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。

    在获取js签名的时候需要把当前的url中除hash外的部分做encodeURIComponent后传给微信的api。

  2. 复制粘贴功能。安卓和ios支持的选中复制元素的api不同,所以需要根据平台做兼容处理。

    function setClipboardData(params) {
    const { data } = params;
    const isiOS = !!window.navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
    
    if (data && document.execCommand) {
    let textarea = document.getElementById('J_clipboard_textarea');
    
    if (!textarea) {
      textarea = document.createElement('input');
      textarea.id = 'J_clipboard_textarea';
      textarea.style.opacity = 0;
      textarea.setAttribute('value', data);
      document.body.appendChild(textarea);
    }
    
    if (isiOS) {
      const range = document.createRange();
    
      textarea.contentEditable = true;
      textarea.readOnly = true;
    
      range.selectNodeContents(textarea);
      window.getSelection().addRange(range);
      textarea.setSelectionRange(0, 100);
    } else {
      textarea.select();
    }
    
    if (document.execCommand('copy')) {
      if (isiOS) {
        window.getSelection().removeAllRanges();
      }
      document.body.removeChild(textarea);
      return true;
    }
    
    document.body.removeChild(textarea);
    return false;
    

} return Promise.reject(); } ```

  1. 调用window.location.go(-1)时,返回时页面没有刷新(由于我们使用的是vue,可以很清楚的看到created没有执行)。所使用的测试机是一台iphone 6s plus,在别的机型上也有发现,导致在确认订单更换收货地址以及添加收货地址后返回地址列表时都未能及时更新。

    监听window下的pageshow方法,在pageshow方法中对页面进行reload。

    window.addEventListener('pageshow', (e) => {
        // 当网页来自缓存时,重新reload
        if (e.persisted) {
            window.location.reload();
        }
    });
    

以上就是这三个问题的处理办法了。探究过程还是经历了一番曲折的。

下面听我细细道来......

公众号二次分享

公众号网页二次分享的问题,通过charls抓包并且把线上代码复制到本地,然后用charls做MAP LOCAL, 定位到了分享不成功是因为wx.config有问题了,通过设置wx.error看到报出了 invalid signature的错误。当时怀疑是signature不正确,就对比两个获取jsSignature的请求,发现二次分享的页面上多了from=xxx&isappinstalled=0的参数,然后尝试在发请求前把这两个参数去掉,结果仍然报invalid signature错误。

然后就去找到后端的同事,让他把调用参数给我,然后我自己在微信js接口签名校验工具里测试,测试的结果和接口返回的结果是一样的,于是排除了签名本身的问题。后来就搁置了一段。

后来还是有点不甘心,就接着在网上找答案。经过多次关键词搜索,终于找到了线索。问题就出现在from=xxx&isappinstalled=0这两个参数上。正是因为这两个参数导致了微信sdk配置signature错误。然后试着在vue的created里对href做检测并替换掉from=xxx&isappinstalled参数,然后重新复制href。

问题到这里就结束了。

复制粘贴板安卓和ios兼容性问题

之前有同事写了复制粘贴板的代码,我只是调用。后来测试的同事发现丝毫没效果。然后我就对复制粘贴板的代码进行了一番改造。刚开始没什么头绪,就去网上找一些成型的代码。后来在stackoverflow发现了一段代码,对原来的代码稍作改造,可以了。然后就兴奋的发上线。然而,事情并没有那么简单...

在安卓和网页上是好的,但是在ios上document.execCommand('copy')直接返回了false。让我有点郁闷。然后几经查找,发现el.select在ios下是不能运行的,这段代码存在兼容性问题。后来又针对ios写了另外一段复制的代码。最终解决了这一问题。

window.location.go(-1)刷新问题

这个问题发生在一个iphone6sp的测试机上,我本人用的iphone8,并不存在这个问题,页面正常地重新执行了。起初以为只是那台机器有问题,就找了一台iphone6p做测试,发现在6p下是好的。加之还有别的事情要忙,就先放一边了。

过了一会儿测试同事说又有一台iphone6也有这个问题,然后觉得这个问题也许并不是某个机型的问题,而是一类机型都存在这个问题,于是就着手处理这个问题。通过map local调试,发现vue的created没有执行,而且vue的组件并没有用keep-alive包裹,于是把问题定位在了页面刷新的问题上,进而定位到了页面返回时调用的window.history.go这个api上。在网上找了一些这个api的信息,然后说的是返回并刷新,但是貌似并没有刷新啊...

后来经过一番查找和多次试验,终于找到了一个救命稻草————pageshow, 通过监听pageshow,当页面返回调用window.location.go时,会出发pageshow,然后顺利地解决了这个问题。

大概就是这三个问题了,不过遇到问题也是一种收获,希望每天的工作都能有所得吧。