ios中微信不能识别H5中二维码的解决方案汇总

蛰伏已久 蛰伏已久 2019-03-20

这几天心血来潮,用vue开发一个H5页面,H5最后一页是长按识别二维码,可是死活都识别不出来,百度了各种方法,折腾了好几个小时,记录一下,避免以后踩坑。

二维码识别原理

当微信客户端识别到用户在img标签内进行长按操作时,会立刻截屏然后启动二维码识别算法。

这里有2个关键词,首先是“img标签”,也就是说,要识别的二维码必须放到img标签中,而不能采用background-image的形式。

其次是“截屏”,为什么微信要采用截屏而不是使用img中的图片呢?这是因为截屏不用考虑网络传输的问题,可以立即启动二维码识别算法,减少用户长按后的等待时间。截屏要求我们必须保证这几点才能识别:

  • 二维码必须要显示全,如果有一部分被屏幕或者其他元素遮挡,那是识别不出来的

  • 二维码周围不要过于复杂,防止识别算法识别错误

  • img不能太小了,不能太模糊,否则都识别不出来

  • 网页没有加载完成,微信的识别js没有启动

解决过程记录

最开始,我是考虑原来的二维码图片太小,太模糊,因此更换了清晰的图片,并把img尽可能放大,结果还是失败。

考虑到是不是z-index层级的问题,把二维码的z-index层级设置到最高,其他的层级设置为-1,有一定的效果,我的iphone 5s可以识别了,但是别的iphone手机还是不行,说明不是正确的解决方案

百度看了下ios下微信确实有这个bug,一般的解决方案是

  • 定位由absolute绝对定位改为margin形式,,据说fixed和absolute定位会导致这个问题,但是我的项目不用绝对定位不好做的

  • 给img添加一个大于64px的padding,试了这个办法,解决不了不能识别的问题,但是可以增加识别的面积

  • 还有的说给img的父元素设置一个背景,然后把img往父元素左上角移动一些距离,img透明度设为0,这个办法也试了,无效

后来看到有人说

经反复实验之后,发现代码中用到了window.history.replaceState(null, null, newUrl);以及window.location.href=newUrl,将此类代码注释掉,发现二维码可识别。

考虑是不是我使用的是vue的问题,vue-router引起的,结果百度一下,果然发现是这个问题,

解决方法有3个:

  • 将vue-router的history模式改为hash模式,我正是采用这个方法解决的

  • 进入该页面的方式不使用路由跳转,而改为 <a href="xxx">目标二维码页面</a>的方式;未测试

  • 在beforeCreated中重载该页面(例如增加&_r=1);未测试


感觉这应该是微信的bug,和vue应该没有关系,至此终于完美解决了,总结一下。

  • 使用img标签嵌入二维码,而不是background-image

  • 二维码不能过小,不能模糊,不能被遮挡

  • 给img增加一个padding,增大识别区域,让用户操作方便

  • vue-router使用hash模式,不要使用history模式




分享到

点赞(0)