直接上代碼:
1. 前端調試代碼:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>調用微信相機</title> <link rel="stylesheet" href="css/weui.min.css"/> </head> <body> <br/><br/> <div> <div class="hd"> <h1 class="page_title" ><span id="current_user"></span></h1> </div> <br/> <div class="page slideIn button"> <div class="bd spacing"> <br/><br/><br/><br/> <a class="weui_btn weui_btn_primary" href="javascript:;" onclick="take_a_photo()">調用微信相機</a> </div> </div> </div> <br/><br/><br/><br/> <div> appId:<span id="appId"></span><br/> timestamp:<span id="timestamp"></span><br/> nonceStr:<span id="nonceStr"></span><br/> jsapi_ticket:<span id="jsapi_ticket"></span><br/> signature:<span id="signature"></span><br/> originalStr:<span id="originalStr"></span><br/> scan_result:<span id="result"></span><br/> </div> <script type='text/javascript' src='js/jquery.min.js'></script> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script type="text/javascript" src="js/weixin_util.js"></script> <script type="text/javascript"> // 通過config接口注入權限驗證配置 $(function(){ debugger; get_wx_config(); }) function get_wx_config(){ debugger; //url(當前網頁的URL,不包含#及其後面部分) var url = window.location.href.split('#')[0]; var indata = {"url":url}; //$.post("http://wwww.axxx.cn/xxx/weixin/getConfigInfo.json", indata, function(data){ $.post("http://localhost:8080/xxx/weixin/getConfigInfo.json", indata, function(data){ debugger; if(data.rs == 'f'){ alert("系統錯誤"); }else{ var result = data.body; $("#appId").text(result.appId); $("#timestamp").text(result.timestamp); $("#nonceStr").text(result.nonceStr); $("#jsapi_ticket").text(result.jsapi_ticket); $("#signature").text(result.signature); $("#originalStr").text(result.originalStr); //步驟三:通過config接口注入權限驗證配置 wx.config({ debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。 appId: result.appId, // 必填,公眾號的唯一標識 timestamp: result.timestamp, // 必填,生成簽名的時間戳 nonceStr: result.nonceStr, // 必填,生成簽名的隨機串 signature: result.signature,// 必填,簽名,見附錄1 jsApiList: ["chooseImage", "previewImage", "uploadImage", "downloadImage"] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 // 基本思路是,上傳圖片到微信服務器->下載多媒體接口講圖片下載到服務器->返回服務器存儲路徑->前台顯示 }); // 步驟四:通過ready接口處理成功驗證 wx.ready(function(){ alert("wx.config success."); }); wx.error(function(res){ alert("wx.config failed."); //alert(res); // config信息驗證失敗會執行error函數,如簽名過期導致驗證失敗,具體錯誤信息可以打開config的debug模式查看, // 也可以在返回的res參數中查看,對於SPA可以在這裡更新簽名。 }); // {"errMsg":"config:invalid signature"} } },'json'); } // 圖片接口 // 拍照、本地選圖 var images = { localId: [], serverId: [] }; // 拍照或者選擇照片 function take_a_photo(){ wx.chooseImage({ count: 1, // 默認9,這裡每次只處理一張照片 sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有 sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有 success: function (res) { images.localId = res.localIds; // 返回選定照片的本地ID列表,localId可以作為img標簽的src屬性顯示圖片 var i = 0, length = images.localId.length; function upload() { wx.uploadImage({ localId: images.localId[i], success: function(res) { i++; alert('已上傳:' + i + '/' + length); images.serverId.push(res.serverId); // res.serverId 就是 media_id,根據它去微信服務器讀取圖片數據: var indata = {"media_id":res.serverId}; $.post("/weixin/getPhoto.json", indata, function(data){ if(data.rs == 'f'){ alert("系統錯誤"); }else{ alert(data.body); // 返回 圖片在我們自己的服務器的url } },'json'); if (i < length) { upload(); } }, fail: function(res) { alert(JSON.stringify(res)); } }); } upload(); } }); } </script> </body> </html>
前端這裡
var url = window.location.href.split('#')[0];
是比較容易犯錯的地方。
2. 後端接口:
@NoLogin @RequestMapping(value="/getConfigInfo.json", method=RequestMethod.POST) @ResponseBody public Object getConfigInfo(String url) throws NoSuchAlgorithmException{ String noncestr = "dsfww"; JsapiTicket ticket = AccessTokenJsapiTicketThread.getTicket(); logger.debug("ticket::::::;" + JSON.toJSONString(ticket)); System.out.println("ticket::::::;" + JSON.toJSONString(ticket)); if(ticket != null){ long timestamp = new Date().getTime(); StringBuilder sb = new StringBuilder("jsapi_ticket="); sb.append(ticket.getTicket()).append("&noncestr=").append(noncestr) .append("×tamp=").append(timestamp).append("&url=").append(url); MessageDigest md = MessageDigest.getInstance("SHA-1"); // 對接後的字符串進行sha1加密 byte[] digest = md.digest(sb.toString().getBytes()); String signature = SignUtil.byteToStr(digest).toLowerCase(); Map<String, String> map = new HashMap<String, String>(); map.put("jsapi_ticket", ticket.getTicket()); map.put("appId", WxPayConfPub.APPID); map.put("timestamp", String.valueOf(timestamp)); map.put("nonceStr", noncestr); map.put("signature", signature); map.put("originalStr", sb.toString()); logger.debug(JSON.toJSONString(map)); System.out.println(JSON.toJSONString(map)); return JsonConvertor.convertSuccessResult(map); } return JsonConvertor.convertFailResult(ErrorCodeEnum.SYSTEM_ERROR); } @NoLogin @RequestMapping(value="/getPhoto.json", method=RequestMethod.POST) @ResponseBody public Object getPhoto(String media_id) throws NoSuchAlgorithmException{ //http請求方式: GET,https調用 // var url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID"; AccessToken token = AccessTokenJsapiTicketThread.accessToken; String url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=" + token.getAccess_token() + "&media_id=" + media_id; HttpsURLConnection httpsUrl = null; InputStream inputStream = null; Date now = new Date(); String saveFileName = null; try { httpsUrl = HttpUtil.initHttpsConnection(url, "GET"); int responseCode = httpsUrl.getResponseCode(); if (responseCode == 200) { // 從服務器返回一個輸入流 inputStream = httpsUrl.getInputStream(); byte[] data = new byte[1024]; int len = 0; FileOutputStream fileOutputStream = null; saveFileName = DateUtil.convertYMDH(now) + RandomStringUtils.random(6, true, true) + ".jpg";; // 絕對路徑 String path = imageRootPath + DateUtil.convertYMD(now) + "/" + saveFileName; File dir = new File(imageRootPath + DateUtil.convertYMD(now) + "/"); if (!dir.exists()) { FileUtils.forceMkdir(dir); } try { fileOutputStream = new FileOutputStream(path); while ((len = inputStream.read(data)) != -1) { fileOutputStream.write(data, 0, len); } fileOutputStream.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { } } if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { } } } } } catch (IOException e) { e.printStackTrace(); } // 返回圖片路徑 return JsonConvertor.convertSuccessResult(DateUtil.convertYMD(now) + "/" + saveFileName); }
/getConfigInfo.json 接口是配置 jsapi 權限認證。
/getPhoto.json 是從 微信服務器下載照片,保存到我們自己的服務器上。然後將我們自己服務器的地方返回給前端使用。