最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

记录--微信调用jssdk全流程详解

来源:博客园


【资料图】

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

微信调用jssdk全流程详解

系统框架使用的是前后端分离,前端使用vant,后端是springboot

一、网页授权的时序图

二、公众号配置

1. 绑定域名

登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。也就是这样:

点击设置之后,弹出这样一个输入框,输入服务器所在的域名:

2:引入js文件

直接在你的页面里引入js文件就行

<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

三、前端方法

1. 初始化方法,从后台获取基本的参数

前端进入需要扫一扫功能的页面时候,在mounted方法里面,执行微信配置getWxConfig(),此方法主要是获取jssdk所需要的参数,先检查本地缓存的是否过期,过期则请求后台获取

export function getWxConfig() {  //判断signature是否过期  if (expireSign()) {    let data = {};    data.appId = localStorage.getItem("appId");    data.timestamp = localStorage.getItem("timestamp");    data.nonceStr = localStorage.getItem("nonceStr");    data.signature = localStorage.getItem("signature");    setWxConfig(data);  } else {    //如果过期了,请求后台获取    let url = location.href.split("#")[0]; //获取锚点之前的链接,防止出现invalid signature错误    wxSign({ url: url })      .then(res => {        console.log(res);        if (res.code == 200) {          localStorage.setItem("appId", res.data.appId);          localStorage.setItem("timestamp", res.data.timestamp);          localStorage.setItem("nonceStr", res.data.nonceStr);          localStorage.setItem("signature", res.data.signature);          localStorage.setItem("expireSignTime", res.data.expireTime);          setWxConfig(res.data);        } else {          localStorage.removeItem("expireSignTime");          Toast.fail("网络故障,请退出重新加载页面");        }      })      .catch(error => {        localStorage.removeItem("expireSignTime");        Toast.fail("网络故障,请退出重新加载页面");      });  }}

2:注入config配置

上面获取到后台的参数后,在页面使用wx.config接口注入权限验证配置

function setWxConfig(data) {  console.log(data);  wx.config({    debug: false, // true是开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。    appId: data.appId, // 必填,公众号的唯一标识    timestamp: data.timestamp, // 必填,签名的时间戳,后台生成的    nonceStr: data.nonceStr, // 必填,签名的随机串,后台生成的    signature: data.signature, // 必填,签名,后台生成的    jsApiList: ["scanQRCode"] // 必填,需要使用的JS接口列表,scanQRCode是调用扫一扫二维码  });  wx.error(function(res) {    localStorage.removeItem("expireSignTime");    Toast.fail("网络故障,请退出重新页面");  });}

3. 方法调用

config如果不报错,则在 wx.ready里面调用jssdk的方法

wx.ready(function () {        wx.scanQRCode({          needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果          success: function (res) {            let data = res.resultStr; // 当needResult 为 1 时,扫码返回的结果            let code = codeFormat(data);            that.pointCode = code;            that.saveSinglePoint();          },        });      });

四、后端方法

1. 获取access_token和jsapi_Ticket,缓存使用了文件的方式,也支持redis等方式

/** * 获取access_token和jsapi_ticket **/public AppWechatEntity getJsapiTicket() {    //logger.debug("--------------开始执行getJsapiTicket方法--------------");    //定义过期时间    AppWechatEntity appWechatEntity = new AppWechatEntity();    String accessTokenString = "";    String jsapiTicketString = "";    String jsapi_ticket = "";    String access_token = "";    jsapiTicketString = readWechatTokenFile(getJsapiTicketFilePath());    if (!StringUtils.isEmpty(jsapiTicketString)) {        appWechatEntity = JSONObject.parseObject(jsapiTicketString, AppWechatEntity.class);        long expireTime = appWechatEntity.getExpire_time();        long curTime = create_timestamp();        if (expireTime >= curTime && StrUtil.isNotEmpty(appWechatEntity.getJsapi_ticket())) {            //logger.debug("已有的jsapi_ticket=" + jsapi_ticket);            return appWechatEntity;        }    }    long timestamp = create_timestamp() + 7000;//过期时间是2小时(7200s)    access_token =            getAccessTokenData("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + configBeanValue.appid + "&secret=" + configBeanValue.secret);    Map accessTokenMap = new HashMap();    accessTokenMap.put("expire_time", timestamp);    accessTokenMap.put("access_token", access_token);    accessTokenString = JSONObject.toJSONString(accessTokenMap);    jsapi_ticket = getJsapiTicketData("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi");    Map jsapiTicketMap = new HashMap();    jsapiTicketMap.put("expire_time", timestamp);    jsapiTicketMap.put("jsapi_ticket", jsapi_ticket);    jsapiTicketString = JSONObject.toJSONString(jsapiTicketMap);    // 写文件    try {        FileUtils.writeStringToFile(new File(getAccessTokenFilePath()), accessTokenString, CharsetUtil.CHARSET_UTF_8);        FileUtils.writeStringToFile(new File(getJsapiTicketFilePath()), jsapiTicketString, CharsetUtil.CHARSET_UTF_8);        //logger.debug("写入文件成功");    } catch (IOException e) {        log.debug("写文件异常:" + e.getMessage());        e.printStackTrace();    }    appWechatEntity.setJsapi_ticket(jsapi_ticket);    appWechatEntity.setExpire_time(timestamp);    appWechatEntity.setAccess_token(access_token);    //logger.debug("--------------结束执行getJsapiTicket方法--------------");    return appWechatEntity;}

2.根据jsapi_ticket获取signature

上面获取了jsapi_ticket之后,使用jsapi_ticket,noncestr,timestamp和前端传入的url组装成签名字符串,使用sha1进行加密,返回到前端

/** * 生成signature **/@Overridepublic AppWechatEntity sign(String url) {    Map ret = new HashMap();    String nonceStr = create_nonce_str();    String timestamp = Long.toString(create_timestamp());    String string1;    String signature = "";    //获取jsapi_ticket和过期时间    AppWechatEntity appWechatEntity = getJsapiTicket();    String jsapiTicket = appWechatEntity.getJsapi_ticket();    Long expireTime = appWechatEntity.getExpire_time();    //注意这里参数名必须全部小写,且必须有序    string1 = "jsapi_ticket=" + jsapiTicket +            "&noncestr=" + nonceStr +            "×tamp=" + timestamp +            "&url=" + url;    try {        MessageDigest crypt = MessageDigest.getInstance("SHA-1");        crypt.reset();        crypt.update(string1.getBytes(StandardCharsets.UTF_8));        signature = byteToHex(crypt.digest());    } catch (Exception e) {        e.printStackTrace();    }    appWechatEntity.setAppId(configBeanValue.appid);    appWechatEntity.setExpire_time(expireTime);    appWechatEntity.setNonceStr(nonceStr);    appWechatEntity.setTimestamp(timestamp);    appWechatEntity.setSignature(signature);    return appWechatEntity;}

3. 后端全部的代码

/**     * 生成signature     **/    @Override    public AppWechatEntity sign(String url) {        Map ret = new HashMap();        String nonceStr = create_nonce_str();        String timestamp = Long.toString(create_timestamp());        String string1;        String signature = "";        //获取jsapi_ticket和过期时间        AppWechatEntity appWechatEntity = getJsapiTicket();        String jsapiTicket = appWechatEntity.getJsapi_ticket();        Long expireTime = appWechatEntity.getExpire_time();        //注意这里参数名必须全部小写,且必须有序        string1 = "jsapi_ticket=" + jsapiTicket +                "&noncestr=" + nonceStr +                "×tamp=" + timestamp +                "&url=" + url;        try {            MessageDigest crypt = MessageDigest.getInstance("SHA-1");            crypt.reset();            crypt.update(string1.getBytes(StandardCharsets.UTF_8));            signature = byteToHex(crypt.digest());        } catch (Exception e) {            e.printStackTrace();        }        appWechatEntity.setAppId(configBeanValue.appid);        appWechatEntity.setExpire_time(expireTime);        appWechatEntity.setNonceStr(nonceStr);        appWechatEntity.setTimestamp(timestamp);        appWechatEntity.setSignature(signature);        return appWechatEntity;    }      /**     * 获取jsapi_ticket     **/    public AppWechatEntity getJsapiTicket() {        //logger.debug("--------------开始执行getJsapiTicket方法--------------");        //定义过期时间        AppWechatEntity appWechatEntity = new AppWechatEntity();        String accessTokenString = "";        String jsapiTicketString = "";        String jsapi_ticket = "";        String access_token = "";        jsapiTicketString = readWechatTokenFile(getJsapiTicketFilePath());        if (!StringUtils.isEmpty(jsapiTicketString)) {            appWechatEntity = JSONObject.parseObject(jsapiTicketString, AppWechatEntity.class);            long expireTime = appWechatEntity.getExpire_time();            long curTime = create_timestamp();            if (expireTime >= curTime && StrUtil.isNotEmpty(appWechatEntity.getJsapi_ticket())) {                //logger.debug("已有的jsapi_ticket=" + jsapi_ticket);                return appWechatEntity;            }        }        long timestamp = create_timestamp() + 7000;//过期时间是2小时(7200s)        access_token =                getAccessTokenData("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + configBeanValue.appid + "&secret=" + configBeanValue.secret);        Map accessTokenMap = new HashMap();        accessTokenMap.put("expire_time", timestamp);        accessTokenMap.put("access_token", access_token);        accessTokenString = JSONObject.toJSONString(accessTokenMap);        jsapi_ticket = getJsapiTicketData("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi");        Map jsapiTicketMap = new HashMap();        jsapiTicketMap.put("expire_time", timestamp);        jsapiTicketMap.put("jsapi_ticket", jsapi_ticket);        jsapiTicketString = JSONObject.toJSONString(jsapiTicketMap);        // 写文件        try {            FileUtils.writeStringToFile(new File(getAccessTokenFilePath()), accessTokenString, CharsetUtil.CHARSET_UTF_8);            FileUtils.writeStringToFile(new File(getJsapiTicketFilePath()), jsapiTicketString, CharsetUtil.CHARSET_UTF_8);            //logger.debug("写入文件成功");        } catch (IOException e) {            log.debug("写文件异常:" + e.getMessage());            e.printStackTrace();        }        appWechatEntity.setJsapi_ticket(jsapi_ticket);        appWechatEntity.setExpire_time(timestamp);        appWechatEntity.setAccess_token(access_token);        //logger.debug("--------------结束执行getJsapiTicket方法--------------");        return appWechatEntity;    }    public String getAccessToken() {        //logger.debug("--------------开始执行getAccessToken方法--------------");        String access_token = "";        String accessTokenString = "";        AppWechatEntity appWechatEntity = new AppWechatEntity();        accessTokenString = readWechatTokenFile(getAccessTokenFilePath());        if (StringUtils.isNotEmpty(accessTokenString)) {            appWechatEntity = JSONObject.parseObject(accessTokenString, AppWechatEntity.class);            access_token = appWechatEntity.getAccess_token();            long expireTime = appWechatEntity.getExpire_time();            long curTime = create_timestamp();            if (expireTime >= curTime) {                //logger.debug("已有的access_token=" + access_token);                return access_token;            }        }        long timestamp = create_timestamp() + 6000;//过期时间是2小时,但是可以提前进行更新,防止前端正好过期        access_token =                getAccessTokenData("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + configBeanValue.appid + "&secret=" + configBeanValue.secret);        Map accessTokenMap = new HashMap();        accessTokenMap.put("expire_time", timestamp);        accessTokenMap.put("access_token", access_token);        accessTokenString = JSONObject.toJSONString(accessTokenMap);        // 写文件        try {            FileUtils.writeStringToFile(new File(getAccessTokenFilePath()), accessTokenString, CharsetUtil.CHARSET_UTF_8);            //logger.debug("写入文件成功");        } catch (IOException e) {            log.debug("写文件异常:" + e.getMessage());            e.printStackTrace();        }        //logger.debug("新的access_token=" + access_token);        //logger.debug("--------------结束执行getAccessToken方法--------------");        return access_token;    }    private String readWechatTokenFile(String filePath) {        String content = "";        try {            if (new File(filePath).exists()) {                FileReader fileReader = new FileReader(filePath, CharsetUtil.CHARSET_UTF_8);                content = fileReader.readString();            } else {                new File(filePath).createNewFile();            }        } catch (IOException e) {            log.error("读文件异常:" + e.getMessage());            e.printStackTrace();        }        return content;    }    private String getAccessTokenData(String url) {        String str = "";        String result = HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);        if (StringUtils.isBlank(result))            return str;        str = parseData("access_token", "expires_in", result);        return str;    }    private String getJsapiTicketData(String url) {        String str = "";        String result = HttpUtil.get(url, CharsetUtil.CHARSET_UTF_8);        if (StringUtils.isBlank(result))            return str;        str = parseData("ticket", "expires_in", result);        return str;    }    private String parseData(String tokenName, String expiresInName, String data) {        String tokenConent = "";        JSONObject jsonObject = JSONObject.parseObject(data);        try {            tokenConent = jsonObject.get(tokenName).toString();            if (StringUtils.isEmpty(tokenConent)) {                log.error("token获取失败,获取结果" + data);                return tokenConent;            }        } catch (Exception e) {            log.error("token 结果解析失败,token参数名称: " + tokenName + "有效期参数名称:" + expiresInName + "token请求结果:" + data);            e.printStackTrace();            return tokenConent;        }        return tokenConent;    }    private String byteToHex(final byte[] hash) {        Formatter formatter = new Formatter();        for (byte b : hash) {            formatter.format("%02x", b);        }        String result = formatter.toString();        formatter.close();        return result;    }    private String create_nonce_str() {        return IdUtil.simpleUUID();    }    private Long create_timestamp() {        return System.currentTimeMillis() / 1000;    }    private String getJsapiTicketFilePath() {        return configBeanValue.tokenpath + "/" + configBeanValue.appid + "_jsapiTicket.txt";    }    private String getAccessTokenFilePath() {        return configBeanValue.tokenpath + "/" + configBeanValue.appid + "_accessToken.txt";    }

五.vue weixin-js-sdk进行微信分享

第一步:安装weixin-js-sdk

npm install weixin-js-sdk

第二步:

在assets文件下新建个common文件夹,然后再新建个utils.js文件

import wx from "weixin-js-sdk"; /** 微信分享* 获取微信加签信息* @param{data}:获取的微信加签* @param{shareData}:分享配置参数*/export const wexinShare = (data, shareData) => {let appId = data.appId;let timestamp = data.timestamp;let nonceStr = data.nonceStr;let signature = data.signature;wx.config({debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId: appId, // 必填,公众号的唯一标识timestamp: timestamp, // 必填,生成签名的时间戳nonceStr: nonceStr, // 必填,生成签名的随机串signature: signature, // 必填,签名,见附录1jsApiList: ["updateAppMessageShareData", "updateTimelineShareData"] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2});wx.ready(function () {//分享到朋友圈”及“分享到QQ空间”wx.updateTimelineShareData({title: shareData.title, // 分享标题link: shareData.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致imgUrl: shareData.imgUrl, // 分享图标success: function (res) {// 设置成功// console.log("分享成功返回的信息为:", res);}}) //“分享给朋友”及“分享到QQ”wx.updateAppMessageShareData({title: shareData.title, // 分享标题desc: shareData.desc, // 分享描述link: shareData.link, // 分享链接imgUrl: shareData.imgUrl, // 分享图标success: function (res) {// console.log("分享成功返回的信息为:", res);;}}) });wx.error(function (res) {// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。console.log("验证失败返回的信息:", res);});}

第三步:调用

import {wexinShare} from "@/common/utils.js";
//请求微信配置参数接口(获取签名),由后台给接口给get_share(){    var that = this;    var urls = that.$qs.stringify(window.location.href.split("#")[0]);        //看后台请求接口是get/post    that.$axios.post("/xxx",urls).then((res) => {       if (res.data) {    //微信加签    var obj = {    appId: res.data.appId,    nonceStr: res.data.nonceStr,    signature: res.data.signature,    timestamp: res.data.timestamp    }    //分享数据,这段主要是为了在hash模式下分享出去的链接不被浏览器截取,保证完全把链接分享出去    var shareWxLink = window.location.href.split("#")[0] + "static/redirect.html?redirect=" + encodeURIComponent(window.location.href) + "&pid_uid=" + userinfo.uid;    // console.log("shareWxLink", shareWxLink)    let shareData = {    title: "标题", // 分享标题    link: shareWxLink,    imgUrl: "http://xxx.jpg", // 分享图标    desc: "这里填写简介文字"    }        //引用    wexinShare(obj, that, shareData);    } else {    that.$toast("获取sdk参数失败!");    }    }) } 

本文转载于:

https://blog.csdn.net/m0_56961433/article/details/116135543

https://blog.csdn.net/u014678583/article/details/106024611

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

关键词: 开始执行 参数信息 参数名称