根据微信接口文档写了一个分享功能,结果一开始就报invalid signature 签名错误,搞得很头大,卡了三天,期间一直百度,几乎各类错误调试都试了,最后在一篇文章中看到:前端传递的url地址是通过 encodeURIComponent的,因此后台接收到须要 decode 一下,才恍然大明白了。由于微信获取code值的时候就是须要encodeURI的,而后通过调试,通车了。今天把可能的状况都罗列一下;前端
invalid signature签名错误建议按以下顺序检查:ajax
(1)确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。算法
(2)确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。json
(3)确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。api
(4)确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。缓存
(5)确保必定缓存access_token和jsapi_ticket。服务器
(6)若是是卡劵调用接口为:微信
"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card"app
日常接口:dom
"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"
若是以上方法都试过了,仍是报签名错误,如下方法或许能够解决
一、查一下反向代理服务器,有可能映射的地址和实际地址是有出入的
二、若是你用的是静态页面,在你配置wx.config以前,先经过location.href.split('#')[0]把当前url编码传递到后台,后台经过
URLDecoder.decode(url, "UTF-8");解码,解码是必须的;
贴上个人主要代码 /<![CDATA[*/ var contextPath = /*[[@{/}]]*/ ''; /*]]>/
$(function(){ var url=location.href.split('#')[0]; var req={ url:url } $.ajax({ url:contextPath+'getJSParams', data:req, dataType:'json', type:'post', async:true, success:function(data){ console.log(data.appId); console.log(data.noncestr); console.log(data.signature); console.log(data.timestamp); console.log(url); var appId=data.appId; var nonceStr=data.noncestr; var signature=data.signature; var timestamp=data.timestamp; wx.config({ debug:false, appId:appId, timestamp:timestamp, nonceStr:nonceStr, signature:signature, jsApiList: [ 'checkJsApi', 'onMenuShareAppMessage' ] }); } }); }); function shareMessage(){ wx.ready(function(){ wx.onMenuShareAppMessage({ title: '', desc: '', link: '', imgUrl: '', trigger: function (res) { // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,由于客户端分享操做是一个同步操做,这时候使用ajax的回包会尚未返回 // alert('用户点击发送给朋友'); }, success: function (res) { alert('已分享'); }, cancel: function (res) { alert('已取消'); }, fail: function (res) { alert(JSON.stringify(res)); } }); wx.error(function(conf) { console.log(conf); console.log(conf.errMsg); // config信息验证失败会执行error函数,如签名过时致使验证失败,具体错误信息能够打开config的debug模式查看,也能够在返回的res参数中查看,对于SPA能够在这里更新签名。 }); }) } /** * 获取微信js接口参数 * * [@param](https://my.oschina.net/u/2303379) request * [@param](https://my.oschina.net/u/2303379) model * [@return](https://my.oschina.net/u/556800) */ @RequestMapping(value = "getJSParams", method = {RequestMethod.POST}) @ResponseBody public String getJSParams(HttpServletRequest request, Model model) { String url = request.getParameter("url"); WXJSParams wxjsParams = new WXJSParams(); try { url = URLDecoder.decode(url, "UTF-8"); logger.info("获取微信js接口参数url之一" + url); wxjsParams = wechatUserService.getJSParams(model, url); } catch (Exception e) { logger.info("获取微信js接口参数出错:" + e.getMessage()); } return JSONObject.toJSONString(wxjsParams); } /** * 获取微信js参数 * * @param model * @param url * @return */ @Override public WXJSParams getJSParams(Model model, String url) { String jsApiTicket = customerJsApiTicketRepository.find(); //随机字符串 String noncestr = StringUtil.getStringRandom(16); //时间戳 String timestamp = String.valueOf(System.currentTimeMillis() / 1000); //注意这里参数名必须所有小写,且必须有序 String tempStr = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url; //sha1加密 String signature = EncryptUtil.SHA1(tempStr); WXJSParams wxjsParams = new WXJSParams(); wxjsParams.setAppId(appid); wxjsParams.setNoncestr(noncestr); wxjsParams.setSignature(signature); wxjsParams.setTimestamp(timestamp); logger.info("微信js参数wxjsParams:" + wxjsParams); logger.info("微信js参数jsApiTicket:" + jsApiTicket); return wxjsParams; }