H5实现 js-sdk 微信扫一扫

2023-12-30 03:50:57

H5实现 js-sdk 微信扫一扫

配置和绑定域名

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

微信公众平台

https://mp.weixin.qq.com/

在这里插入图片描述

手机扫码登录

在这里插入图片描述

如图所示,进行配置(将第四步文件下载,上传到指定位置),如:

1、springboot项目,放在项目中resources文件夹下,保证 域名+项目名+该文件名 能访问到

域名填写为 域名+项目名

2、直接放在服务器的目录中,可通过nginx转发达到可以访问即可

域名填写为域名

在这里插入图片描述

备注:登录后可在“开发者中心”查看对应的接口权限。

引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js

如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。

加入如下资源即可

    <link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.0.0/weui.min.css">
    <script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
    <script src="https://res.wx.qq.com/open/libs/weuijs/1.1.4/weui.min.js"></script>

备注:支持使用 AMD/CMD 标准模块加载方法加载

前端代码
var jsApiList = [
        'checkJsApi',
        'scanQRCode'
    ];

    function init() {
        // console.log("url = " + location.href.split("#")[0])
        //获取签名
        $.ajax({
            url:"你的后台地址",
            method:"post",
            data:{url:location.href.split("#")[0]},
            dataType: "json",
            success:function (data) {
                console.info("data = " , data);
                var appId = data['appId'];
                var timestamp = data['timestamp'];
                var nonceStr = data['nonceStr'];
                var signature = data['signature'];


                //1 通过config接口注入权限验证配置
                wx.config({
                    debug: false, ///  // true是开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: appId,
                    timestamp: timestamp,
                    nonceStr: nonceStr,
                    signature: signature,
                    jsApiList: jsApiList
                });

                //2 通过ready接口处理成功验证
                wx.ready(function () {
                    //check client vserion wether support JS API
                    wx.checkJsApi({
                        jsApiList: ['scanQRCode'],
                        success: function (res) {
                            // weui.alert(res.errMsg);

                            wx.scanQRCode({
                                needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                                scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
                                success: function (res) {
									console.log(res)
                                    
                                }
                            });

                        }
                    });
                });

                //3 通过error接口处理失败验证
                //wrong error msg
                wx.error(function (res) {
                    weui.alert("出错了请稍后再试!" + res.errMsg);
                });
            },
            error:function (data) {
                weui.alert("网络异常,请稍后再试。");
            }
        });
    }

    //scanning Qr code
    function scanQRCodeFun() {
        // 初始化,成功后,会调用微信扫一扫
        init();

    };
后端代码
获取 Access token

在这里插入图片描述

仅是示例,可根据自己情况修改

WX_APPIDWX_APPSECRET替换成自己的

public String getWxAccessToken() throws IOException {
        String getUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WX_APPID+"&secret="+WX_APPSECRET;
        String res = "";
        // 创建一个URL对象
        URL url = new URL(getUrl);
        // 打开一个连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 设置请求方式为GET
        connection.setRequestMethod("GET");
        // 设置连接超时时间
        connection.setConnectTimeout(5000);
        // 设置读取超时时间
        connection.setReadTimeout(5000);
        // 发送请求
        connection.connect();
        // 获取响应码
        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            // 获取响应内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            // 解析响应内容
            System.out.println(sb.toString());
            res = sb.toString();
        } else {
            System.out.println("响应码:" + responseCode);
        }
        // 关闭连接
        connection.disconnect();
        return res;
    }
获取 jsapi_ticket

生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

  1. 参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
  2. 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功返回如下JSON:

{
  "errcode":0,
  "errmsg":"ok",
  "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
  "expires_in":7200
}

获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

在这里插入图片描述

仅是示例,可根据自己情况修改

wxAccessToken就是上面获取到的

public String getWxJsapiTicket(String wxAccessToken) throws IOException {
        String getUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+wxAccessToken+"&type=jsapi";
        String res = "";
        // 创建一个URL对象
        URL url = new URL(getUrl);
        // 打开一个连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 设置请求方式为GET
        connection.setRequestMethod("GET");
        // 设置连接超时时间
        connection.setConnectTimeout(5000);
        // 设置读取超时时间
        connection.setReadTimeout(5000);
        // 发送请求
        connection.connect();
        // 获取响应码
        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            // 获取响应内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            // 解析响应内容
            System.out.println(sb.toString());
            res = sb.toString();
        } else {
            System.out.println("响应码:" + responseCode);
        }
        // 关闭连接
        connection.disconnect();
        return res;
    }
权限签名

WX_APPID替换成自己的

// 签名用的url必须是调用JS接口页面的完整URL
    public Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
        System.out.println(string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        ret.put("appId",WX_APPID);
        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }

    private static 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 static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

然后在控制层将结果返回到前端

在这里插入图片描述

注意

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

文章来源:https://blog.csdn.net/m0_59139771/article/details/135300248
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。