这两天做h5微信登陆接入,踩了不少坑,这里分享下,虽然没什么技术含量,但也能让后来者可以少走点弯路,看完可以一次解决你所有问题
我们在做微信登陆时可以先去微信测试号弄一个测试账号 ,可以不用先去注册
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
扫码登陆完有测试 appid 跟正式版一毛一样
这里只分享前端接入
首先填入网页授权回调域名,注意这里只填入域名(也就是你页面的访问地址),不需要 http://.
登陆功能前端只需要获取code就可以了,然后发给服务端处理,这一步这里就省略了
<script>
const appid = 'wxfa34e18dd574f910';
const scope = 'snsapi_userinfo';
const code = GetUrlParam('code');
const localurl = window.location.href
const url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + appid + '&redirect_uri=' + localurl + '&response_type=code&scope=' + scope + '&state=STATE#wechat_redirect';
if (code == null || code == '') {
window.location.href = url;
} else {
httpRequest({
httpUrl: 'https://***?code=' + code,
type: 'get',
}, (data) => {
console.log('获取到登陆数据')
console.log(data)
})
}
//获取参数方法
function GetUrlParam(paraName) {
let url = document.location.toString();
let arrObj = url.split("?");
if (arrObj.length > 1) {
var arrPara = arrObj[1].split("&");
var arr;
for (var i = 0; i < arrPara.length; i++) {
arr = arrPara[i].split("=");
if (arr != null && arr[0] == paraName) {
return arr[1];
}
}
return "";
} else {
return "";
}
}
</script>
接下来是分享功能,分享功能看了文档只能接入jssdk
首先是设置 js安全接口域名,注意这里也只填域名,不需要http://
接下来你需要获取到签名
主要问题基本就出在签名这块 ,虽然看似麻烦,单其实也就两个 GET 请求而已
一 获取access_token
https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=自己的APPID&secret=自己的APPSECRET
二 获取 jsapi_ticket
https请求方式: GET https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=第一步获取的access_tooken&type=jsapi
获取到 jsapi_ticket 后就进行 sha1签名 获取到签名
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value
其中 noncestr 跟timestamp 都是自己填写啊,注意noncestr 有限定长度
文档有提供例子,可以直接下载生成签名
http://demo.open.weixin.qq.com/jssdk/sample.zip
备注:链接中包含php、java、nodejs以及python的示例代码供第三方参考,第三方切记要对获取的accesstoken以及jsapi_ticket进行缓存以确保不会触发频率限制
这里注意 url 必须跟配置填的一致,且必须重前端获取,记得要 encodeURIComponent ,生成的签名可以用下面签名校验接口验证下对不对
附上两个调试接口
https://mp.weixin.qq.com/debug/cgi-bin/apiinfo?t=index&type=基础支持&form=获取access_token接口%20/token。(assets_token 调试接口)
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign。 (签名校验接口)
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62 (签名文档,传送门)
最后附上例子
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
let signUrl = encodeURIComponent(location.href.split('#')[0])
// let e_signUrl = signUrl)
httpRequest({
httpUrl: 'https://***?url=' + signUrl,
type: 'get',
}, (data) => {
console.log(data)
data = JSON.parse(data)
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'wxfa34e18dd574f910', // 必填,公众号的唯一标识
jsApiList: [
'checkJsApi',
'updateAppMessageShareData',
'updateTimelineShareData',
'getLocation'
], // 必填,需要使用的JS接口列表
nonceStr: data.data.nonceStr, // 必填,生成签名的随机串
signature: data.data.signature,// 必填,签名
timestamp: data.data.timestamp, // 必填,生成签名的时间戳
});
})
wx.ready(function () {
// 1 判断当前版本是否支持指定 JS 接口,支持批量判断
// document.querySelector('#checkJsApi').onclick = function () {
wx.checkJsApi({
jsApiList: [
'getNetworkType',
'previewImage'
],
success: function (res) {
alert(JSON.stringify(res));
}
});
wx.updateAppMessageShareData({
title: '互联网之子',
desc: '在长大的过程中,我才慢慢发现,我身边的所有事,别人跟我说的所有事,那些所谓本来如此,注定如此的事,它们其实没有非得如此,事情是可以改变的。更重要的是,有些事既然错了,那就该做出改变。',
link: 'http://movie.douban.com/subject/25785114/',
imgUrl: 'http://img3.douban.com/view/movie_poster_cover/spst/public/p2166127561.jpg',
success: function () {
// 设置成功
}
});
wx.updateTimelineShareData({
title: '互联网之子',
link: 'http://movie.douban.com/subject/25785114/',
imgUrl: 'http://img3.douban.com/view/movie_poster_cover/spst/public/p2166127561.jpg',
success: function () {
// 设置成功
}
})
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
console.log(res)
}
});
})
</script>
http.js
function httpRequest(paramObj, fun, errFun) {
var xmlhttp = null;
/*创建XMLHttpRequest对象,
*老版本的 Internet Explorer(IE5 和 IE6)使用 ActiveX 对象:new ActiveXObject("Microsoft.XMLHTTP")
* */
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
/*判断是否支持请求*/
if (xmlhttp == null) {
alert('你的浏览器不支持XMLHttp');
return;
}
/*请求方式,并且转换为大写*/
var httpType = (paramObj.type || 'GET').toUpperCase();
/*数据类型*/
var dataType = paramObj.dataType || 'json';
/*请求接口*/
var httpUrl = paramObj.httpUrl || '';
/*是否异步请求*/
var async = paramObj.async || true;
/*请求参数--post请求参数格式为:foo=bar&lorem=ipsum*/
var paramData = paramObj.data || [];
var requestData = '';
for (var name in paramData) {
requestData += name + '=' + paramData[name] + '&';
}
requestData = requestData == '' ? '' : requestData.substring(0, requestData.length - 1);
/*请求接收*/
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
/*成功回调函数*/
fun(xmlhttp.responseText);
} else {
/*失败回调函数*/
errFun;
}
}
/*接口连接,先判断连接类型是post还是get*/
if (httpType == 'GET') {
xmlhttp.open("GET", httpUrl, async);
xmlhttp.send(null);
} else if (httpType == 'POST') {
httpUrl += requestData;
xmlhttp.open("POST", httpUrl, async);
//发送合适的请求头信息
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(requestData);
}
}
主要注意的那几个点都用红字标出来了,只要注意那几个点一般没问题,还有问题可以加我v交流。aa785954118
最后如果对你有帮助的话不妨给点给点感谢费,毕竟有这个能节省你最少两天的头痛 !哈哈哈