微信 JSSDK 教程以及在Vue中实战教程

Hi,很高兴认识你~

世界很大,巧妙的是我们在这里相遇。

欢迎关注天宇文创意乐派,一个职场人的聚集地。

一.官方教程

官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html

官方文档——常见的错误及解决方法:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html     ——>  见页面底端的 附录5-常见错误及解决方法

官方问题反馈:https://developers.weixin.qq.com/community/develop/doc/0000e2f5d0cdc02c0a391aedd58c00

官方校验签名工具:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

官方demo:https://www.weixinsxy.com/jssdk/

二.常见问题以及需要注意的地方

1. invalid signature签名错误。建议按如下顺序检查:    1. 确认签名算法正确,可用http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。    2. 确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。    3. 确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。    4. 确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。    5. 确保一定缓存access_token和jsapi_ticket。    6. 确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent,后端接收url时且必须用例如:Java URLDecoder.decode解码),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。2.invalid domain?    配置的url与公众号JS接口安全域名不匹配

三.绑定JS接口安全域名

域名格式:如果你的项目域名是http://test.domain.com,那么JS接口安全域名为test.domain.com。切记!

四.引入JSSDK

第一种引入方式:

npm install jweixin-module --save

第二种引入方式:

在需要调用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)<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

代码实现:

前端

import wx from 'weixin-js-sdk';async _goWxchat(){  let url = encodeURIComponent(location.href.split('#')[0]);  let data={  url  }  alert(url)  const res = await reqConfigSignature(data);  if (res.code === RESULT_SUCCESS_CODE) {    //拿到后端给的这些数据    let appId = res.data.appId;      let timestamp = res.data.timestamp;    let nonceStr = res.data.nonceStr;    let signature = res.data.signature;    wx.config({      debug: true,// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。      appId,         // 必填,公众号的唯一标识,填自己的!(开发者账号)      timestamp, // 必填,生成签名的时间戳,刚才接口拿到的数据      nonceStr,   // 必填,生成签名的随机串      signature, // 必填,签名,见附录1      jsApiList: [        'onMenuShareTimeline',        'onMenuShareAppMessage'      ]    })    wx.ready(function () {      //分享到朋友圈      wx.onMenuShareTimeline({        title: '小婊子',   // 分享时的标题        link: url + '?redirectUrl=http://auth.motopa.cn/logo.png',     // 分享时的链接  如果项目域名与JS接口安全域名不一致 可以采用此方式        imgUrl: '',    // 分享时的图标        success: function () {          console.log("分享成功");        },        cancel: function () {          console.log("取消分享");        }      });      //分享给朋友      wx.onMenuShareAppMessage({        title: tit,        desc: '这件商品终于优惠了,每件只需元',        link: url + '?redirectUrl=http://auth.motopa.cn/logo.png',        imgUrl: '',        type: '',        dataUrl: '',        success: function () {          console.log("分享成功");        },        cancel: function () {          console.log("取消分享");        }      });    })    wx.error(function(res){    })  }},

后端

package com.auth.sdk.controller;import com.alibaba.fastjson.JSONObject;import com.auth.sdk.common.ResultData;import com.auth.sdk.db.redisson.dao.base.StringRedisBaseDao;import lombok.extern.slf4j.Slf4j;import org.apache.commons.codec.digest.DigestUtils;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import java.net.URLDecoder;import java.util.Arrays;import java.util.Random;@RestController@RequestMapping("/wx")@Slf4jpublic class WxShareController {    private static final String appId = "wxea6631d168a33e95";    private static final String appSecret= "3eae75d6a79a9af781391c9c1460026f";    private static final long expireTime = 120l;    @Autowired    RestTemplate restTemplate;    //redis 可以替换成自己环境的redis    @Autowired    StringRedisBaseDao stringRedisBaseDao;    /**     * 获取最终签名的restful方法     * @param reqJson     * @return     */    @PostMapping("/WeixinAction_getWXConfigSignature")    public ResultData getWXConfigSignature(@RequestBody JSONObject reqJson) {        String url = URLDecoder.decode(reqJson.getString("url"));        log.info("原始URL: " + url);        String timestamp = Long.toString(System.currentTimeMillis() / 1000);        String nonceStr = getRandomStr(8);        log.info("随机串:"+nonceStr+", 获取签名URL: " + url);        JSONObject respJson = new JSONObject();        String[] signArr = new String[]{"url=" + url, "jsapi_ticket=" + getWXJsapiTicket(), "noncestr=" + nonceStr, "timestamp=" + timestamp};        Arrays.sort(signArr);        String signStr = StringUtils.join(signArr, "&");        String resSign = DigestUtils.sha1Hex(signStr);        log.info("返回的签名:" + resSign);        respJson.put("appId", appId);        respJson.put("timestamp", timestamp);        respJson.put("nonceStr", nonceStr);        respJson.put("signature", resSign);        log.info(respJson.toJSONString());        return ResultData.success(respJson);    }    /**     * 获取jsapi_ticket方法     * @return     */    private String getWXJsapiTicket() {        String ticket = stringRedisBaseDao.getItem(appId);        if (StringUtils.isBlank(ticket)) {            String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + getWXaccessToken() + "&type=jsapi";            String resp = restTemplate.getForObject(url, String.class);            JSONObject resJson = JSONObject.parseObject(resp);            log.info("获取到ticket:" + resJson.getString("ticket"));            stringRedisBaseDao.addItem(appId, resJson.getString("ticket"), expireTime);            return resJson.getString("ticket");        }        return ticket;    }    /**     * 获取access_token     * @return     */    private String getWXaccessToken() {        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;        String resp = restTemplate.getForObject(url, String.class);        JSONObject resJson = JSONObject.parseObject(resp);        log.info("获取到access_token:" + resp);        return resJson.getString("access_token");    }    /**     * 随机字符串     * @param length     * @return     */    public static String getRandomStr(int length) {        String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";        int randomNum;        char randomChar;        Random random = new Random();        // StringBuffer类型的可以append增加字符        StringBuffer str = new StringBuffer();        for (int i = 0; i < length; i++) {            // 可生成[0,n)之间的整数,获得随机位置            randomNum = random.nextInt(base.length());            // 获得随机位置对应的字符            randomChar = base.charAt(randomNum);            // 组成一个随机字符串            str.append(randomChar);        }        return str.toString();    }}

微信分享步骤测试 建议在wechat开发工具中测试

配置 switchhost  将本机指向JS接口安全域名

    

本文使用 文章同步助手 同步

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容