主要功能:調用微信圖片選擇接口,用戶確定之後將圖片上傳到七牛雲,然後將返回的圖片地址保存到本地數據庫對應字段
踩的坑
- 微信JSDDK 1.1.0和1.2.0的差異
- 安卓手機和IOS的差異
主要表現在wx.chooseImage
和wx.uploadImage
,還有選擇圖片之後獲取到如: wxlocalresource://imageid123456789987654321
這樣的圖片地址,IOS無法預覽,或者wx.uploadImage
接口在IOS上只能上傳一張圖片。
實現的思路
- 通過
wx.chooseImage
接口讓用戶選擇圖片,選擇之後生成預覽 - 通過
wx.uploadImage
接口將圖片上傳到微信服務器做臨時素材 - 通過七牛雲fetch接口去下載微信服務器上的圖片
代碼實現
引入權限驗證
// config權限驗證
function wxconfig(url){
$.post('/weixin/configvalid', {'url':url.toString()}, function(data){
wx.config({
debug: false,
appId: data.appId,
timestamp: data.timestamp,
nonceStr: data.nonceStr,
signature: data.signature,
/* jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage']*/
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'translateVoice',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'onVoicePlayEnd',
'pauseVoice',
'stopVoice',
'uploadVoice',
'downloadVoice',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'closeWindow',
'scanQRCode',
'chooseWXPay',
'openProductSpecificView',
'addCard',
'chooseCard',
'openCard',
'openAddress',
'getLocalImgData'
]
});
});
}
導包 (這裏我們用微信JSJDK 1.2.0)
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
選擇圖片,上傳圖片參考官方demo(我是遇到了一大籮筐問題之後纔看到這個救命的demo)
// 5 圖片接口
// 5.1 拍照、本地選圖
var images = {
localId: [],
serverId: []
};
document.querySelector('#chooseImage').onclick = function () {
wx.chooseImage({
success: function (res) {
images.localId = res.localIds;
alert('已選擇 ' + res.localIds.length + ' 張圖片');
}
});
};
// 5.3 上傳圖片
document.querySelector('#uploadImage').onclick = function () {
if (images.localId.length == 0) {
alert('請先使用 chooseImage 接口選擇圖片');
return;
}
var i = 0, length = images.localId.length;
images.serverId = [];
function upload() {
wx.uploadImage({
localId: images.localId[i],
success: function (res) {
i++;
alert('已上傳:' + i + '/' + length);
images.serverId.push(res.serverId);
if (i < length) {
upload();
}
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
}
upload();
};
這個上傳的例子可以解決圖片只能上傳一張的問題,我們就基於這個例子改進我們的代碼。
wxconfig(window.location);
// 5 圖片接口
// 5.1 拍照、本地選圖
var images = {
localId: [],
serverId: []
};
var arrayImgs = new Array();
document.querySelector('#uploaderInput').onclick = function () {
wx.chooseImage({
success: function (res) {
images.localId = res.localIds;
//生成預覽 區分一下ios跟其他系統
var localIds = res.localIds;
if(window.__wxjs_is_wkwebview){
//alert(localIds[0])
for (id in localIds) {
wx.getLocalImgData({
localId: localIds[id],
success: function (res) {
var localData = res.localData;
localData = localData.replace('jgp', 'jpeg');
var tmpl = '<img class="weui-uploader__file weui-uploader__file_status" src="'+localData+'" data-src="'+localIds[id]+'"/>';
$("#uploaderFiles").append(tmpl)
},
fail:function(res){
alert(res.errMsg);
}
});
}
}else{
//遍歷數組
for (id in localIds){
var tmpl = '<img class="weui-uploader__file weui-uploader__file_status" src="#url#" data-src="#url#"/>';
$("#uploaderFiles").append($(tmpl.replace(/#url#/ig, localIds[id])));
}
}
}
});
};
// 5.3 上傳圖片
document.querySelector('#upload_img1').onclick = function () {
if (images.localId.length == 0) {
alert('請先選擇圖片');
return;
}
var i = 0, length = images.localId.length;
images.serverId = [];
function upload() {
wx.uploadImage({
localId: images.localId[i],
success: function (res) {
arrayImgs[i] = res.serverId
console.log(typeof(arrayImgs))
i++;
//alert('已上傳:' + i + '/' + length);
images.serverId.push(res.serverId);
if (i < length) {
upload();
}else{
// 循環結束
topost(arrayImgs)
}
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
}
upload();
};
最後向後臺服務器發送請求
function topost(obj){
var resImgurl = obj.join(",")
$.ajax({
url: '/qiniuImg',
data: {
"resImgurl":resImgurl,
"content":"測試"
},
type: 'post',
dataType: 'json',
cache: false,
success: function(data){
console.log(data)
if(data.re){
console.log("成功寫入數據庫,進行頁面跳轉!")
alert(data.msg)
location.replace('/index');
}else{
alert(data.msg)
}
}
});
}
後臺獲取圖片
String resImgurl = getPara("resImgurl");
// 獲取圖片信息
List<String> imgurl = new ArrayList<String>();
int i = 0;int j = 1;
String[] media_list = resImgurl.split(",");
for (String media_id : media_list) {
String key = QianNiuUpload.fetchTmpFile(media_id, "");
String url = QianNiuUpload.domain + key;
imgurl.add(url);
}
....
將圖片的url 寫入數據庫
QianNiuUpload.java
public class QianNiuUpload {
//設置好賬號的ACCESS_KEY和SECRET_KEY
public static String ACCESS_KEY = "xxxxxx";
public static String SECRET_KEY = "xxxxxx";
//要上傳的空間
public static String bucketname = "xxxxxx";
public static String domain = "http://xxxxxxx.com/"; // 空間的域名
//上傳到七牛後保存的文件名
public static String key = "隨意,這個例子我們沒用到";
//上傳文件的路徑
public static String FilePath = "隨意,這個例子我們沒用到";
//密鑰配置
public static Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
//第二種方式: 自動識別要上傳的空間(bucket)的存儲區域是華東、華北、華南。
public static Zone z = Zone.autoZone();
public static Configuration c = new Configuration(z);
//創建上傳對象
private static UploadManager uploadManager = new UploadManager(c);
//簡單上傳,使用默認策略,只需要設置上傳的空間名就可以了
public static String getUpToken() {
return auth.uploadToken(bucketname);
}
public static void upload() throws IOException {
try {
//調用put方法上傳
Response res = uploadManager.put(FilePath, key, getUpToken());
//打印返回的信息
System.out.println(res.bodyString());
} catch (QiniuException e) {
Response r = e.response;
// 請求失敗時打印的異常的信息
System.out.println(r.toString());
try {
//響應的文本信息
System.out.println(r.bodyString());
} catch (QiniuException e1) {
//ignore
}
}
}
//定義兩個成員變量常量
//獲取臨時素材(視頻不能使用https協議)
public static final String GET_TMP_MATERIAL = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";
//獲取臨時素材(視頻)
public static final String GET_TMP_MATERIAL_VIDEO = "http://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";
//獲取微信服務器中生成的媒體文件
//由於視頻使用的是http協議,而圖片、語音使用http協議,故此處需要傳遞media_id和type
public static String fetchTmpFile(String media_id, String type){
try {
String token = AccessTokenApi.getAccessToken().getAccessToken();
String url = null;
//視頻是http協議
if("video".equalsIgnoreCase(type)){
url = String.format(GET_TMP_MATERIAL_VIDEO, token, media_id);
}else{
url = String.format(GET_TMP_MATERIAL, token, media_id);;
}
URL Nurl = new URL(url);
//構造一個帶指定Zone對象的配置類
Configuration cfg = new Configuration(Zone.autoZone());
Auth me = Auth.create(ACCESS_KEY,SECRET_KEY);
BucketManager bucketManager = new BucketManager(me, cfg);
// bucketManager.fetch("外源圖片地址", "要上傳的七牛目標資源文件夾", "文件名");
// 這邊的文件名如果省略 七牛會隨機給個名字
FetchRet fetchRet = bucketManager.fetch(url,bucketname);
//System.out.println(fetchRet.hash);
System.out.println(fetchRet.key);
//System.out.println(fetchRet.mimeType);
//System.out.println(fetchRet.fsize);
return fetchRet.key;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
java 後臺七牛返回的上傳後的文件名
七牛雲存儲空間可以看到圖片已經成功上傳了