微信内H5页面打开手机APP功能,使用开放标签

3,674 阅读6分钟

前言

手机浏览器跳转APP是可以用Url Scheme的,但是在微信打开的页面中确不能使用Url Scheme,原因在于微信将Url Scheme功能给禁用了,那么怎么解决呢,微信虽然禁了该方式,但是给咱们开放了另外一种方式,也就是按照微信官方文档的步骤来,毕竟是别人的地盘,咱只能照做,不过官方文档写的并不详细,而且非常多的坑,稍不注意就掉进去了,这里我对该功能进行了总结,希望能帮助到大家。

实现的需求

app分享到微信的H5卡片网页(https的网页),用户打开该网页后上方有一个打开APP的按钮,如果手机已经安装了APP,则直接打开APP,如果未安装则跳转到应用市场进行下载

实现原理

利用微信提供的开放标签wx-open-launch-app,来进行跳转,通过该标签还能够得知当前手机是否安装app,如果已安装则打开app,未安装则跳转应用宝,在ios下应用宝会自动跳转App Store去,我们可以巧妙的利用这个功能。官方文档-开放标签说明

准备工作

  1. 微信公众号(已认证的服务号),拿到开发者ID(AppID)和开发者密码(AppSecret),并设置IP白名单(计算签名的服务器IP)

image.png

  1. 该服务号必须绑定JS接口安全域名,也就是移动端H5页面的域名

image.png

  1. 关联移动应用(APP)的绑定关系,微信开放平台准备一个账号,主体需要和微信公众的服务号一致,并将服务号绑定在微信开放平台账号下,并在开放平台内绑定app,并设置域名与所需跳转的app,并拿到绑定的移动应用的AppID关联说明文档

image.png

准备工作完成后应该拿到的3样东西,不清楚的看准备工作章节

  1. 开发者ID(AppID),开发者密码(AppSecret)

  2. 移动应用关联的APPID

开始开发

app开发人员也需要提前接入SDK,才能使用,否则跳转不生效,接入文档,接入后可以分享页面到微信,以卡片的形式展示(只有分享的页面才能使用打开app功能,在微信内容通过点击链接是不行的)

前后端开发流程说明

由于实现整个过程需要后端来计算一个签名,所以需要先后端开发一个接口给前端,前端需要将当前页面的url传到后端参与签名,后端将签名信息返回给前端。具体请查看以下内容

后端开发工作

签名步骤

  1. 获取access_token 官方文档
appid和secret参数就是开发者ID(AppID),开发者密码(AppSecret)

GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

成功后会拿到access_token

{"access_token":"sdfad.....1561","expires_in":7200}
  1. 获取jsapi_ticket,用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期2小时,后端需要对jsapi_ticket全局缓存,微信有请求次数限制)
GET https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功后会得到ticket

{
  "errcode":0,
  "errmsg":"ok",
  "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
  "expires_in":7200
}
  1. 计算签名,官方文档

拼接参数

jsapi_ticket参数为上一个步骤拿到的ticket,noncestr为随机字符串,timestamp为当前时间戳,url为当前前端页面的URL地址(不包含#后面的字符,所以这里最好做成活的,让前端传过来),字段名和字段值都采用原始值,不进行URL 转义

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

对拼接后的字符串进行sha1签名,得到signature

0f9de62fce790f9a083d5c99e95740ceb90c27ed

将下面的参数返回给前端即可

{
  appId: '', // 开发者ID(AppID)
  timestamp: , // 生成签名的时间戳
  nonceStr: '', // 生成签名的随机字符串
  signature: '',// sha1签名
}

前端开发工作

  1. 请求后端提供的接口获取签名

  2. 引入JS-SDK

<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
  1. 通过SDK的config方法将 请求后端得到的签名信息传入配置项
wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: ['checkJsApi'], // 必填,需要使用的JS接口列表,没有就随便填一个
  openTagList: ['wx-open-launch-app'] //必填, 要申请的开放标签名称
})

将调试模式打开,当在微信内打开分享的该H5页面后,页面弹出 ok 字样就说明验证成功了

  1. 在vue项目内使用开放标签 appid就是移动应用关联的APPID,extinfo为需要传递给app的参数(仅支持字符串类型),launch事件为用户点击了跳转app按钮,error为跳转app失败事件
<wx-open-launch-app  appid="关联的app应用id" :extinfo="extinfo" @launch="wxlaunchFn" @error="wxerrorFn"> 
     <script type="text/wxtag-template">  
         <style>.btn {padding: 12px;}</style>
         <p class="btn">在APP内打开</button>
      </script>
</wx-open-launch-app>

注意事项:只有在签名,域名,都验证成功后,开放标签才会显示,否则什么都看不见

可以在打开失败的事件下,做判断,如果未安装app,则跳转应用市场让用户选择下载安装app

  wxerrorFn(e){
      //console.log('fail' , e);
      if(e.detail.errMsg === 'launch:fail') {
        //console.log('未安装app, 跳转应用宝地址');
        window.location.href = "https://a.app.qq.com/o/simple.jsp?pkgname=xxxx";
      } else if(e.detail.errMsg === 'launch:fail_check fail'){
        //console.log('appid未绑定未关联到微信');
      }
    },

其它补充

只有在签名,域名,都验证成功后,开放标签才会显示,否则是看不见开放标签按钮的

开放标签的样式只能写在 里面的style标签内,写在外面是不生效的

可以将开放标签外面套一个div,然后div定位到需要的地方,用自己的按钮显示在那个位置,然后将开放标签内的按钮设置成透明,盖在上面,这样方便调试样式(原理:用户看见的是我们自己的按钮,实际点击到的是微信的开放标签按钮)

为了便于调试可以使用 微信开发者工具 - 公众网页 - 下进行调试,调试时是需要将代码放到JS安全域名下的服务器上的,所以每修改代码都要提交到服务器,非常繁琐,(可以通过配置host来实现本地调试,将安全域名映射到本地服务器然后搭配微信开发者工具进行预览调试)

注意,当公司有多个服务号的时候,容易搞混账号这3个参数 开发者ID(AppID),AppSecret,应用APPID,导致验证失败,这个特别注意

注意,如果有人删了微信公众号内的安全域名,刚删除时 签名校验也会提示Ok,但是但是 点击打开app是没有反应的,所以如果代码没有改动 而点击打开app没反应那么首先去检查安全域名是否被正确