绑定域名
- 登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”
Vue项目引入微信JS-sdk
- 方式一:使用
npm install weixin-js-sdk
- 方式二:在vue项目下public文件夹下的index.html页面,引入微信配置文件
····
<!-- 引入微信配置文件 -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
····
权限配置
- 通过
config
接口注入权限验证配置
所有需要使用 JS-SDK 的页面必须先注入配置信息,否则将无法调用(同一个 url 仅需调用一次,对于变化 url 的 SPA 的 web app 可在每次 url 变化时进行调用,目前 Android 微信客户端不支持 pushState 的 H5 新特性,所以使用 pushState 来实现 web app 的页面会导致签名失败,此问题会在 Android6.2 中修复)。
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,在pc端时会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '', // 必填,签名
jsApiList: [], // 必填,需要使用的JS接口列表
openTagList: ['wx-open-launch-weapp'] // 微信开放标签
})
- 通过
ready
接口处理成功验证
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
// config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。
// 对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
- 通过
error
接口处理失败验证
wx.error(function(res){
// config信息验证失败会执行error函数,
// 如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
项目中封装JS-SDK config 方法
// /utils/wechat.js
import wx from 'weixin-js-sdk'
import getSignature from '@/api'
/**
* @description 微信config方法封装
* @param {string} url 授权网页链接
* @param {array} apiList 使用的JS接口列表
* @param {array} openTagList 使用的开放标签列表
* @returns Promise
*/
export function weixinAuth ( url, apiList = ['wx-open-launch-weapp', 'getLocation', 'openLocation'] openTagList = ['wx-open-launch-weapp']) {
if (!is_weixn()) {
return
}
return new Promise((resolve,reject) => {
getSignature({ url }).then(res => {
if (res.appId) {
wx.config({
debug: false,
appId: res.appId,
timestamp: res.timeStamp,
nonceStr: res.nonceStr,
signature: res.signature,
jsApiList: apiList,
openTagList: openTagList
})
wx.ready(res => {
resolve(res, wx)
})
}
}).catch(err => {
reject(err)
})
})
}
/**
* @description 判断使用终端是否为IOS
* @returns Boolean
*/
export function isIOS () {
const isIphone = navigator.userAgent.includes('iPhone')
const isIpad = navigator.userAgent.includes('iPad')
return isIphone || isIpad
}
/**
* @description 判断是否微信环境
* @returns Boolean
*/
function is_weixn() {
let ua = navigator.userAgent.toLowerCase()
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true
} else {
return false
};
};
页面中调用
- 单独页面的使用
import { weixinAuth } from '@/utils/wechat'
export default {
create(){
const url = window.location.href
weixinAuth(url)
}
}
- 全局引用
import { weixinAuth, isIOS } from '@/utils/wechat'
router.beforeEach(async (to, from, next) => {
// 路由守卫处理IOS
if (isIOS()) {
if (from.path === '/') {
weixinAuth,isIOS({ url: location.href.split('#')[0] })
}
}
})
JS-SDK签名算法--后端生成
- appId 和 appsecret 只需登录“微信公众平台”--“开发”--“基本设置”
- url则是前台传过来的当前页面的地址值
- access_token获取
public String getAccessToken(String appId , String appSecret){
// 网页授权接口
String GetPageAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
HttpClient client = null;
String access_token = null;
int expires_in = 0;
try {
client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(GetPageAccessTokenUrl);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = client.execute(httpget, responseHandler);
JSONObject OpenidJSONO = JSONObject.fromObject(response);
access_token = String.valueOf(OpenidJSONO.get("access_token"));//获取access_token
expires_in = Integer.parseInt(String.valueOf(OpenidJSONO.get("expires_in")));//获取时间
} catch (Exception e) {
throw new CommonRuntimeException("获取AccessToken出错!");
} finally {
client.getConnectionManager().shutdown();
}
return access_token;
}
- 获取jsapi_ticket
public String getTicket(String accessToken) {
// 网页授权接口
String GetPageAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";
HttpClient client = null;
String ticket = "";
int expires_in = 0;
try {
client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(GetPageAccessTokenUrl);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = client.execute(httpget, responseHandler);
JSONObject OpenidJSONO = JSONObject.fromObject(response);
ticket = String.valueOf(OpenidJSONO.get("ticket"));//获取ticket
expires_in = Integer.parseInt(String.valueOf(OpenidJSONO.get("expires_in")));//获取时间
} catch (Exception e) {
throw new CommonRuntimeException("获取Ticket出错!");
} finally {
client.getConnectionManager().shutdown();
}
return ticket;
}
- SHA1加密,参数是由url、jsapi_ticket、noncestr、timestamp组合而成
public String SHA1(String str) {
try {
MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1"); //如果是SHA加密只需要将"SHA-1"改成"SHA"即可
digest.update(str.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexStr = new StringBuffer();
// 字节数组转换为 十六进制 数
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexStr.append(0);
}
hexStr.append(shaHex);
}
return hexStr.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
4.获取 Signature
public String getSignature(String url) {
String signature = "";
String appid = *********;//微信公众号的appid
String appsecret = ***********;//微信公众号的appsecret
//获取noncestr
String noncestr = UUID.randomUUID().toString();
//获取timestamp
String timestamp = Long.toString(System.currentTimeMillis() / 1000);
//获取access_token
String access_token = getAccessToken(appid , appsecret);
//获取jspai_ticket
String jsapi_ticket = getTicket(access_token);
//将四个数据进行组合,传给SHA1进行加密
String str = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + noncestr +
"×tamp=" + timestamp +
"&url=" + url;
//sha1加密
signature = SHA1(str);
return signature ;
}
JS-SDK 接口、开放标签使用
自定义“分享给朋友”及“分享到QQ”按钮的分享内容
import weixinAuth from '@/utils/wechat'
export default {
methods:{
shareFriends () {
weixinAuth().then((res, wx) => {
wx.updateAppMessageShareData({
title: '', // 分享标题
desc: '', // 分享描述
link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '', // 分享图标
success: function () {
// 设置成功
}
})
})
}
}
}
公众号打开小程序
基本用法
<template>
<wx-open-launch-weapp
id="launch-btn"
:username="weapp.username"
:path="weapp.path"
@launch="handleLaunchFn"
@error="handleErrorFn"
>
<script type="text/wxtag-template">
<style>
.test-btn{
width:100%;
background: #f24f45;
border-radius: 20px;
padding:0 10px;
color:#fff;
font-size:16px;
border:none;
}
</style>
<button class="test-btn">点我跳转小程序</button>
</script>
</wx-open-launch-weapp>
</template>
<script>
import { weixinAuth } from '@/utils/wechat'
export default {
created () {
const url = window.location.href
wechatUtil.initWechat({ url })
},
}
</script>
使用动态生成标签
- 封装 动态生成微信开放标签(wx-open-launch-weapp)方法
/**
* @description 动态生成微信发放标签
* @param { object:{
* appid {string} 小程序原始id(gh_xxxxxxx)
* url {string} 小程序跳转路径 例 pages/home/home.html - (后面必须带上.html后缀 否则IOS跳转时出现小程序页面未配置)
* eleId {string} 元素id
* content {string} html字符串
* }} info
**/
export function openLaunchWeapp(info) {
if(!is_weixin()){
return false
}
if(is_version()){
var btn = document.getElementById(info.eleId)
let script = document.createElement('script')
script.type = "text-wxtag-template"
script.text = info.content
let html = `
<wx-open-launch-weapp style="width:100%;display:block;" username="${info.appid}" path="${info.url}">
${script.outerHTML}
</wx-open-launch-weapp>`
btn.innerHTML = html
btn.addEventlistener('launch', function (e) {
console.log('success')
})
btn.addEventListener('error',function (e) {
console.log('fail',e.detail)
alert(`跳转异常-${e.detail}`)
})
} else {
alert(`您的版本不支持跳转小程序`)
}
}
// 判断是否微信环境
function is_weixn() {
let ua = navigator.userAgent.toLowerCase()
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true
} else {
return false
};
};
// 判断当前微信版本号是否支持--使用微信开放标签
export function is_version(){
let client = false; // 当前版本号是否支持 (默认不支持)
let wxInfo = navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i); // 微信浏览器信息
// 微信版本号 wxInfo[1] = "7.0.18.1740" (示例)
//进行split转成数组进行判断 [7,0,18,1740] (示例)
let version = wxInfo[1].split(".");
// 判断版本在7.0.12及以上的版本
if (version[0] >= 7) {
if (version[1] >= 0) {
if (version[2] >= 12) {
client = true; // 当前版本支持
}
}
}
return client;
}
- 页面中使用
<template>
<div id="launch-btn"></div>
</template>
<script>
import { openLaunchWeapp } from '@/utils/wechat'
export default {
mounted(){
const weappDom = this.$el.querySelector('.weapp-cover')
openLaunchWeapp({
eleId:"launch-btn", // 元素id
appid: 'gh_xxxx', // 小程序原始id
url: 'pages/home/home.html', // 小程序跳转路径
content: `
<button class="test-btn">点我跳转小程序</button>
<style>
.test-btn{
width:100%;
background: #f24f45;
border-radius: 20px;
padding:0 10px;
color:#fff;
font-size:16px;
border:none;
}
</style>`
})
}
}
</script>