根據微信接口文檔寫了一個分享功能,結果一開始就報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; }