H5跳转小程序

H5跳转小程序

要求

1、已认证的服务号

或者 已认证的非个人主体的小程序,使用小程序云开发的静态网站托管绑定的域名下的网页

2、域名已添加至JS接口安全域名

步骤:公众号直达 - 【设置与开发】-【公众号设置】-【功能设置】-【JS接口安全域名】

域名必须是已备案

3、微信浏览器里打开

在微信浏览器里才能加载开放标签。

后端篇

1、获取Access token

请求地址
https://api.weixin.qq.com/cgi-bin/token
请求类型

GET

请求参数
{
  grant_type: 'client_credential',
  appid: '【公众号后台】-【设置与开发】-【基本设置】-【开发者ID(AppID)】',
  secret: '【公众号后台】-【设置与开发】-【基本设置】-【开发者密码(AppSecret)】',
}

2、获取jsapi_ticket

请求地址
https://api.weixin.qq.com/cgi-bin/ticket/getticket
请求类型

GET

请求参数
{
  type: 'jsapi',
  access_token: '上面获取的access_token',
}

3、生成签名

变量说明
const appid = '【公众号后台】-【设置与开发】-【基本设置】-【开发者ID(AppID)】';
// 随机16位字符串,getNonceStr()是我自己封装的随机生成字符串函数。生成随机字符串网上很多,就不展开讲了
const noncestr = getNonceStr(16);
const jsapi_ticket = '上一步获取的jsapi_ticket';
// 取十位时间戳,默认时间戳是十三位
const timestamp = Math.round(new Date().getTime() / 1000).toString();
// url应该由前端传,前端没传就手动从请求头里拿
const url = requestUrl || ctx.request.header.referer;

时间戳这里是世纪大坑!很多文章都不提及过这一点,正确需要的时间戳应该是十位的

大坑2!url前端传的时候注"转码"一下,例如:’#’, ‘中文’, ‘特殊字符’

  • 参与签名的字段包括有效的 jsapi_ticket(获取方式详见微信 JSSDK 文档), noncestr (随机字符串,由开发者随机生成),timestamp (由开发者生成的当前时间戳), url(当前网页的URL,不包含#及其后面部分。注意:对于没有只有域名没有 path 的 URL ,浏览器会自动加上 / 作为 path,如打开 http://qq.com 则获取到的 URL 为 http://qq.com/)。
排序变量
const string1 = `jsapi_ticket=${jsapi_ticket}&noncestr=${noncestr}&timestamp=${timestamp}&url=${url}`;
  • 对所有待签名参数按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串 string1。这里需要注意的是所有参数名均为小写字符
加密排序后的变量string1
// sha1函数是我封装的加密。实现sha1加密网上很多,就不展开讲了
const signature = sha1(string1);
  • 接下来对 string1 作 sha1 加密,字段名和字段值都采用原始值,不进行 URL 转义。即 signature=sha1(string1)。

生成后如果不放心,可以去官方验签对比一下:微信 JS 接口签名校验工具

返回给前端的格式
const result = {appid, timestamp, noncestr, signature};
return {
  code: 200,
  msg: 'ok',
  data: result
};
完整代码
"use strict";

const Service = require('egg').Service;

const {getNonceStr} = require('../../utils/base');
const {sha1} = require('../../utils/encryption');

class WxService extends Service {
  
  async getSignature(requestUrl) {

    const {ctx, service} = this;

    const appid = '【公众号后台】-【设置与开发】-【基本设置】-【开发者ID(AppID)】';
    // 随机16位字符串,getNonceStr()是我自己封装的随机生成字符串函数。生成随机字符串网上很多,就不展开讲了
    const noncestr = getNonceStr(16);
    const jsapi_ticket = '上一步获取的jsapi_ticket';
    // 取十位时间戳,默认时间戳是十三位
    const timestamp = Math.round(new Date().getTime() / 1000).toString();
    // url应该由前端传,前端没传就手动从请求头里拿
    const url = requestUrl || ctx.request.header.referer;


    const string1 = `jsapi_ticket=${jsapi_ticket}&noncestr=${noncestr}&timestamp=${timestamp}&url=${url}`;
    const signature = sha1(string1);

    // console.log({appid, noncestr, jsapi_ticket, timestamp, url, string1, signature})

    return {appid, timestamp, noncestr, signature};
  }
}

module.exports = WxService;

前端篇

index.html
<!DOCTYPE html>
<html lang="zh-cn">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>wx_h5</title>
  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
  <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>

<body>
  <p>测试</p>

  <div ref="launchBtnHome" class="launchBtnHome">
    <wx-open-launch-weapp id="launch-btn" username="gh_8052c0bb85ba" path="/pages/index/index.html">
      <template>
        <style>
          .btn {
            padding: 12px;
            width: 200px;
            height: 50px;
          }
        </style>
        <button class="btn">打开小程序</button>
      </template>
    </wx-open-launch-weapp>
  </div>

</body>
<script>
  $(document).ready(function () {
    $.get("后端API地址", function (res) {
      console.log(res.data);
      const { appid, timestamp, noncestr, signature } = res.data;
      wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: appid, // 必填,公众号的唯一标识
        timestamp: timestamp, // 必填,生成签名的时间戳
        nonceStr: noncestr, // 必填,生成签名的随机串
        signature: signature,// 必填,签名
        jsApiList: ['chooseImage'], // 必填,需要使用的JS接口列表
        openTagList: ['wx-open-launch-weapp'] // 使用开放标签
      });

      var btn = document.getElementById('launch-btn');
      btn.addEventListener('launch', function (e) {
        console.log('success');
      });
      btn.addEventListener('error', function (e) {
        console.log('fail', e.detail);
      });

      //配置成功之后的函数,按钮生成成功
      wx.ready(() => {
        console.log("ready");
      });
      wx.error(function (res) {
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名
      });

    });
  });
</script>

</html>

闲话篇

如果根据以上步骤还是报错,给几个排查方向:

  1. 服务号是否认证
  2. 是否把访问的连接加在了-JS接口安全域名
  3. 是否在微信浏览器里打开
  4. 检查url,前端打印and后端打印,两个一起看一下是否一样
  5. 更多的报错就要去官方文档看下了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值