当前位置:   article > 正文

UNI-APP 开发微信公众号(H5)JSSDK的使用 (扫一扫为例,后台为 java)_uni-app 开发微信公众号(h5)jssdk 的使用方式

uni-app 开发微信公众号(h5)jssdk 的使用方式


前言

新手入门学习uniapp,所有的坑已踩好,放心观看

一、开始前准备

  1. 准备一个微信公众号,获取基本参数(好像是废话)
    (APPID,APPSECRET)主要是为了获取access_token在这里插入图片描述

  2. 白名单配置,主要是调access_token接口需要添加白名单
    在这里插入图片描述

  3. 最后一步,设置js安全域名,也是坑最多的一步。
    这块配置的这个安全域名必须和h5开发打包后部署的路径一致 微信规定:所有的JS接口只能在公众号绑定的域名下调用 (一看到报这个错,基本上就是这个问题没错了:系统错误,错误码:40048,invalid url domain)
    在这里插入图片描述

二、代码书写

1.前端代码

h5页面直接引入

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

uniapp项目install下

npm i -S weixin-js-sdk
  • 1

模块引入:新建一个模块把,官方js放进去引入
image.png

var wx = require('jweixin-module');
  • 1

前端简单页面书写:
在这里插入图片描述

<template>
	<view class="content">
		<image class="logo" src="/static/logo.png"></image>
		<view >
			<button class="bg-blue" @click="saoma()">扫码</button>
		</view>
	</view>
</template>

<script>
	import wx from 'weixin-js-sdk';
	export default {
		data() {
			return {
				title: 'Hello'
			}
		},
		//所有需要使用JS-SDK的页面必须先注入配置信息,否则无法调用。
		onLoad() {
			uni.request({
			   url:'https://www.×××.com/lk/app/user/getSign',
			   data:{
				   "url":location.href.split('#')[0]
			   },
			   method:"get"
			}).then((res) => {
				console.log(res[1])
			   this.wxConfig(res[1].data.data.appId,res[1].data.data.timestamp,res[1].data.data.nonceStr,res[1].data.data.signature) //以vue为例
			})
		},
		
		methods: {
			wxConfig(_appid,_timestamp,_nonceStr,_signature){
			  var that = this;
			  wx.config({ 
			      debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。   
			      appId: _appid, // 必填,公众号的唯一标识
			      timestamp: _timestamp, // 必填,生成签名的时间戳
			      nonceStr: _nonceStr, // 必填,生成签名的随机串
			      signature: _signature,// 必填,签名
			      jsApiList: [
			                  'checkJsApi',
			                  'startRecord',
			                  'stopRecord',
			                  'translateVoice',
			                  'scanQRCode',// 微信扫一扫接口
			                  'openCard'
			                  ] // 必填,需要使用的JS接口列表 
			  }); 
			  //config信息验证失败会执行error函数
			  wx.error(function(res) {
			      alert("error:" + res.errMsg);
			  });
			  
			  // config信息验证后会执行ready方法,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
			  wx.ready(function() {
			      wx.checkJsApi({
			          jsApiList : ['scanQRCode'],
			          success : function(res) {
			          }
			      });
			  });
			},
			
			saoma(){//页面点击扫码按钮
			    wx.scanQRCode({
			        needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
			        scanType : [ "qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
			        success : function(res) {
 						var result = res.resultStr;
			            if(res.resultStr.indexOf(',') > -1){
			                result = res.resultStr.split(',')[1]; // 当needResult 为 1 时,扫码返回的结果
			            }
			        },
			        fail : function(){
			            console.log('error');
			        }
			    });
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111

2.后端代码

初始化签名接口controllers,签名验签方式我采用的是微信官方demo的工具类,有需要的同学可自己写:

   /**
     * getSign,初始化config信息
     * @return
     */
    @RequestMapping("/getSign")
    @ResponseBody
    public AjaxResult getSign(HttpServletRequest request,String url) throws Exception {
        String jsapi_ticket  = WeChatUtil.getJsapiTicket(WeChatUtil.getAccessToken());
        Map<String, String> ret = WeChatUtil.sign(jsapi_ticket, url);
        return AjaxResult.success("请求成功",ret);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

utils工具类(注:jsapiTicket,accessToken,一般是存缓存,也可建一张表存写。)

package com.ruoyi.project.app.index.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.*;

/**
 * @author jsy
 * @description: 接口请求sign类
 * @date 2021/3/4 16:00
 */
public class WeChatUtil {
    public static 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("url", url);
        ret.put("appId","自己公众号的appid");
        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);
    }
    
  /**
     * 获取access_token(access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token)
     * @return
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static String getAccessToken() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        RestTemplate restTemplate = new RestTemplate(factory());
        Map<String,Object> params = new HashMap<>();
        params.put("APPID","自己公众号的appid");//前面准备工作提到
        params.put("APPSECRET","自己公众号的appsecret");
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
                "&appid={APPID}&secret={APPSECRET}";
        ResponseEntity<String> responseEntity =
                restTemplate.getForEntity(url, String.class,params);
        String body = responseEntity.getBody();
        JSONObject object = JSON.parseObject(body);
        String Access_Token = object.getString("access_token");
        return Access_Token;
    }
      /**
     * 根据token获取jsapiTicket(jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket)
     * @param token
     * @return
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */  
    public static String getJsapiTicket(String token) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        RestTemplate restTemplate = new RestTemplate(factory());
        Map<String,Object> params = new HashMap<>();
        params.put("access_token",token);
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi" +
                "&access_token={access_token}";
        ResponseEntity<String> responseEntity =
                restTemplate.getForEntity(url, String.class,params);
        String body = responseEntity.getBody();
        JSONObject object = JSON.parseObject(body);
        String ticket = object.getString("ticket");
        return ticket;
    }
    /**
     * restTemplate支持https请求
     * @return
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static HttpComponentsClientHttpRequestFactory factory() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        //rest忽略证书访问
        HttpComponentsClientHttpRequestFactory factory = new
                HttpComponentsClientHttpRequestFactory();
        factory.setConnectionRequestTimeout(1000);
        factory.setConnectTimeout(1000);
        factory.setReadTimeout(1000);
        // https
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(null, (X509Certificate[] x509Certificates, String s) -> true);
        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", socketFactory).build();
        PoolingHttpClientConnectionManager phccm = new PoolingHttpClientConnectionManager(registry);
        phccm.setMaxTotal(200);
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).setConnectionManager(phccm).setConnectionManagerShared(true).build();
        factory.setHttpClient(httpClient);
        return factory;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165

总结

到这已经完成啦,小伙伴快去测试用吧,有疑问的请留言。感觉有用的话,点个赞

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/280481
推荐阅读
相关标签
  

闽ICP备14008679号