微信开发:配置 wx.config 实现图像接口(详细配置 wx.config 接口)

约定不等于承诺〃 2023-01-23 06:54 6阅读 0赞

前言

  描述一下大概的应用场景,就是微信的移动端需要拍摄实时图像上传,然后传输到后台,由于我们需要的是直接可以显示的图片,所以要转换成 base 加密后的图片,然后放到 img 标签里进行展示

概述

  简单说一下 JS-SDK 的作用吧,微信 JS-SDK 是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包,可以通过 JS-SDK 使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,要使用 JS-SDK 的第一步就是配置 wx.config 接口,不对第一步是引用 jweixin-1.6.0.js 文件,如果上述文件不可使用就下载这个 jweixin-1.6.0.js ,下边主要讲一下怎么配置 wx.config 接口

配置 wx.config 接口

  首先 wx.config 相当于一个总开关吧,也可以说是一个全局对象,只有通过正确的授权验证才可以使用 JS-SDK 所附带的接口,实际上就相当于一个权限验证,验证成功就可以通过 wx.ready 接口实现,验证失败就进入到了 wx.error 接口

wx.config 接口注入权限验证配置

  1. wx.config({
  2. debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来
  3. appId: '', // 必填,公众号的唯一标识
  4. timestamp: , // 必填,生成签名的时间戳
  5. nonceStr: '', // 必填,生成签名的随机串
  6. signature: '',// 必填,签名
  7. jsApiList: [] // 必填,需要使用的JS接口列表
  8. });

  获取第一个参数生成签名的时间戳(其实就是获取当前时间)

  1. // 时间戳
  2. String timestamp = Long.toString((new Date().getTime()) / 1000);

  获取第二个签名随机串(也没啥特别的就是 UUID)

  1. // 随机串
  2. String nonceStr = UUID.randomUUID().toString();

  获取第三个参数签名!!这个比较重要,签名 = 随机串 + ticket + 时间戳 + URL(当前页面),但是随机串和时间戳我们在上边已经获取到了,下边我们只获取 ticket和当前页面的 URL 就好了,最后把他们拼到一起

  1. /** 获取 signature 的四个步骤 1.获取当前页面 URL 2.获取 access_token 参数 3.通过 access_token 获取 ticket 参数 4.把所有参数拼在一起获取 signature 签名 **/
  2. // 1.url(判断是否有参数如果有参数把参数也拼接上,并且这个路径必须是配置在白名单里边的)
  3. String params = request.getQueryString();
  4. if(StringUtils.isEmpty(params)){
  5. params="";
  6. }else{
  7. params="?"+params;
  8. }
  9. String url = "https://www.baidu.cn"+request.getRequestURI()+params;
  10. // 2. toekn
  11. String access_token = AccessTokenAPI.getAccessToken(appId,appsecret);
  12. // 3.ticket
  13. String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
  14. JSONObject jsonObject = HttpRequestUtil.httpRequest(urlStr, EnumMethod.GET.name(), null);
  15. String ticket = jsonObject.getString("ticket");
  16. // 4.signature
  17. String signature = getsig(nonceStr,ticket,timestamp,url);
  18. // 最后放入 map 中传到页面
  19. Map<String,Object> map = new HashMap<String,Object>();
  20. map.put("appId",appId);
  21. map.put("timestamp",timestamp);
  22. map.put("nonceStr",nonceStr);
  23. map.put("signature",signature);

  定义 AccessToken 实体类并获取 access_tocken 参数(第二步骤)

  1. // AccessToken 实体类
  2. @Data
  3. public class AccessToken {
  4. // 获取到的凭证
  5. private String token;
  6. // 凭证有效时间,单位:秒
  7. private int expiresIn;
  8. }
  9. /** * 公众平台通用接口工具类 * */
  10. public class AccessTokenAPI {
  11. // 获取微信公众号:access_token的接口地址(GET) 限2000(次/天)
  12. public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
  13. /** * 获取access_token */
  14. public static AccessToken getAccessToken(String appid, String appsecret) {
  15. AccessToken accessToken = null;
  16. String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
  17. JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl,EnumMethod.GET.name(), null);
  18. if (jsonObject == null) {
  19. jsonObject = HttpRequestUtil.httpRequest(requestUrl,EnumMethod.GET.name(), null);
  20. }
  21. // 如果请求成功
  22. if (null != jsonObject) {
  23. try {
  24. accessToken = new AccessToken();
  25. accessToken.setToken(jsonObject.getString("access_token"));
  26. accessToken.setExpiresIn(jsonObject.getInteger("expires_in"));
  27. } catch (JSONException e) {
  28. accessToken = null;
  29. // 获取token失败
  30. }
  31. }
  32. return accessToken;
  33. }
  34. }

  拼接 signature 签名的工具类(第四步骤)

  1. private static String getsig(String noncestr,String jsapi_ticket,String timestamp,String url){
  2. String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
  3. "timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url };
  4. Arrays.sort(paramArr);
  5. // 将排序后的结果拼接成一个字符串
  6. String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2])
  7. .concat("&"+paramArr[3]);
  8. String gensignature = null;
  9. try {
  10. MessageDigest md = MessageDigest.getInstance("SHA-1");
  11. // 对拼接后的字符串进行 sha1 加密
  12. System.out.println("拼接加密签名:"+content);
  13. byte[] digest = md.digest(content.getBytes());
  14. gensignature = byteToStr(digest);
  15. } catch (NoSuchAlgorithmException e) {
  16. e.printStackTrace();
  17. }
  18. // 将 sha1 加密后的字符串与 signature 进行对比
  19. if (gensignature != null) {
  20. return gensignature;// 返回signature
  21. } else {
  22. return "false";
  23. }
  24. }
  25. /** * 将字节数组转换为十六进制字符串 * * @param byteArray * @return */
  26. private static String byteToStr(byte[] byteArray) {
  27. String strDigest = "";
  28. for (int i = 0; i < byteArray.length; i++) {
  29. strDigest += byteToHexStr(byteArray[i]);
  30. }
  31. return strDigest;
  32. }
  33. /** * 将字节转换为十六进制字符串 * * @param mByte * @return */
  34. private static String byteToHexStr(byte mByte) {
  35. char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
  36. 'B', 'C', 'D', 'E', 'F' };
  37. char[] tempArr = new char[2];
  38. tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
  39. tempArr[1] = Digit[mByte & 0X0F];
  40. String s = new String(tempArr);
  41. return s;
  42. }

  第四个 jsApiList 实际上是需要调用的接口名字放进去就好了

完整代码

  这是获取 wx.config 授权验证的完整代码

  1. @Service
  2. public class WxConfigUtils {
  3. @Value("${appId}")
  4. private String appId;
  5. @Value("${appSecret}")
  6. private String appSecret;
  7. public Map<String,Object> getWxconfig(HttpServletRequest request){
  8. String params = request.getQueryString();
  9. if(StringUtils.isEmpty(params)){
  10. params="";
  11. }else{
  12. params="?"+params;
  13. }
  14. String url = "https://xxx.xx.cn"+request.getRequestURI()+params;
  15. //request.getRequestURL().toString();
  16. Map<String,Object> map = new HashMap<String,Object>();
  17. // 时间戳
  18. String timestamp = Long.toString((new Date().getTime()) / 1000);
  19. // 随机串
  20. String nonceStr = UUID.randomUUID().toString();
  21. // 获取 access_token
  22. String access_token = AccessTokenAPI.getAccessToken(appId,appSecret);
  23. // 根据 tocker 获取 jstl
  24. String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
  25. JSONObject jsonObject = HttpRequestUtil.httpRequest(urlStr, EnumMethod.GET.name(), null);
  26. String ticket = jsonObject.getString("ticket");
  27. System.out.println("要加密的参数:"+nonceStr+" "+ticket+" "+timestamp+" "+url);
  28. String signature = getsig(nonceStr,ticket,timestamp,url);
  29. map.put("appId",appId);
  30. map.put("timestamp",timestamp);
  31. map.put("nonceStr",nonceStr);
  32. map.put("signature",signature);
  33. return map;
  34. }
  35. private static String getsig(String noncestr,String jsapi_ticket,String timestamp,String url){
  36. String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
  37. "timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url };
  38. Arrays.sort(paramArr);
  39. // 将排序后的结果拼接成一个字符串
  40. String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2])
  41. .concat("&"+paramArr[3]);
  42. String gensignature = null;
  43. try {
  44. MessageDigest md = MessageDigest.getInstance("SHA-1");
  45. // 对拼接后的字符串进行 sha1 加密
  46. System.out.println("拼接加密签名:"+content);
  47. byte[] digest = md.digest(content.getBytes());
  48. gensignature = byteToStr(digest);
  49. } catch (NoSuchAlgorithmException e) {
  50. e.printStackTrace();
  51. }
  52. // 将 sha1 加密后的字符串与 signature 进行对比
  53. if (gensignature != null) {
  54. return gensignature;// 返回signature
  55. } else {
  56. return "false";
  57. }
  58. }
  59. /** * 将字节数组转换为十六进制字符串 * * @param byteArray * @return */
  60. private static String byteToStr(byte[] byteArray) {
  61. String strDigest = "";
  62. for (int i = 0; i < byteArray.length; i++) {
  63. strDigest += byteToHexStr(byteArray[i]);
  64. }
  65. return strDigest;
  66. }
  67. /** * 将字节转换为十六进制字符串 * * @param mByte * @return */
  68. private static String byteToHexStr(byte mByte) {
  69. char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
  70. 'B', 'C', 'D', 'E', 'F' };
  71. char[] tempArr = new char[2];
  72. tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
  73. tempArr[1] = Digit[mByte & 0X0F];
  74. String s = new String(tempArr);
  75. return s;
  76. }
  77. }

前端页面实现

  完整的前端界面,就不上传样式文件了,随便写写样式放个图片就 ok 了

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>调用企业微信图像上传接口</title>
  7. <!--上传图片css-->
  8. <link rel="stylesheet" href="../css/style.css" />
  9. </head>
  10. <body>
  11. <header class="upload-hedaer">
  12. <a href="javaScript:history.back(-1)" class="upload-fh"></a>
  13. <div>上传</div>
  14. <div>···</div>
  15. </header>
  16. <section class="upload-section">
  17. <article class="upload-piclist">
  18. <div class="upload-file" id="uploadfile"></div>
  19. </article>
  20. </section>
  21. <script src="../js/jweixin-1.6.0.js" type="text/javascript" charset="utf-8"></script>
  22. <script src="../js/jquery-3.0.0.min.js" type="text/javascript" charset="utf-8"></script>
  23. <script src="../js/wxconfig.js" type="text/javascript" charset="utf-8"></script>
  24. </body>
  25. <script type="text/javascript"> /** 这个地方我们只需要在要使用的页面引用就 OK 1.chooseImage:和拍照或从手机相册中选图接口 2.getLocalImgData:获取本地图片接口 **/ wx.config({ debug: true, // 生产环境需要关闭debug模式 appId: "[[${appId}]]", // appID = corpID 通过微信服务号/企业微信后台查看 timestamp: "[[${timestamp}]]", // 生成签名的时间戳 nonceStr: "[[${nonceStr}]]", // 生成签名的随机字符串 signature: "[[${signature}]]", // 签名 jsApiList: [ // 需要调用的JS接口列表 'chooseImage', 'getLocalImgData' ] }); </script>
  26. </html>

  我们的 wx.ready 接口是单独写了一个名叫 wxconfig.js 的文件,因为考虑到不止一个页面会用到这个功能,所以写成了公共方法

  1. wx.ready(function(){
  2. var piclist = document.getElementsByClassName('upload-piclist')[0];
  3. //给上传图标绑定onclick事件
  4. $("#uploadfile").click(function(){
  5. // 调取接口
  6. wx.chooseImage({
  7. count: 1, // 默认9
  8. sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
  9. sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
  10. success: function(res) {
  11. wx.getLocalImgData({
  12. localId: res.localIds[0], // 图片的localID
  13. success: function(res) {
  14. var localData = res.localData;
  15. var imageBase64 = '';
  16. if (localData.indexOf('data:image') == 0) {
  17. //苹果的直接赋值,默认生成'data:image/jpeg;base64,'的头部拼接
  18. imageBase64 = localData;
  19. } else {
  20. //此处是安卓中的唯一得坑!在拼接前需要对localData进行换行符的全局替换
  21. //此时一个正常的 base64 图片路径就完美生成赋值到 img 的 src 中了
  22. imageBase64 = 'data:image/jpeg;base64,' + localData.replace(/\n/g, '');
  23. }
  24. var html = document.createElement('div');
  25. html.innerHTML = '<img id="image" src=' + imageBase64 + ' alt="">'
  26. piclist.appendChild(html);
  27. }
  28. });
  29. }
  30. });
  31. })
  32. });

截图示例

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,6人围观)

还没有评论,来说两句吧...

相关阅读

    相关 wxWidgets wxConfig

    wxWidgets提供一个存取配置信息的完整类。可以将配置存放到注册表(windows平台)、类似于windows .INI格式的配置文件(跨平台)等。可惜的是现在还不支持使用

    相关 退款接口开发

    步骤: 发送退款请求到微信->同步告诉你请求成功还是失败->异步回调告诉你退款成功还是失败 说明:微信退款是需要证书的,先要下载证书.如何下载百度一下就可以,很简单 //