直接上代碼:
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 是從 微信服務器下載照片,保存到我們自己的服務器上。然后將我們自己服務器的地方返回給前端使用。
