上傳之前當然要選上傳的文件。
小程序的上傳業務是這個樣的
wx.chooseImage選擇要上傳的文件,會生成對應的臨時path
可以拿這些臨時path去上傳或者預覽。
wx.chooseImage提供的參數比較多:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
count | Number | 否 | 最多可以選擇的圖片張數,默認9 |
sizeType | StringArray | 否 | original 原圖,compressed 壓縮圖,默認二者都有 |
sourceType | StringArray | 否 | album 從相冊選圖,camera 使用相機,默認二者都有 |
success | Function | 是 | 成功則返回圖片的本地文件路徑列表 tempFilePaths |
fail | Function | 否 | 接口調用失敗的回調函數 |
complete | Function | 否 | 接口調用結束的回調函數(調用成功、失敗都會執行) |
為了使用簡單點,我們先來封裝下wx.chooseImage:
chooseImage: function ({sizeType = ['compressed'], sourceType = ['album', 'camera'], count = 9}){
return new es6.Promise((resolve,reject)=>{
wx.chooseImage({
count: count, // 默認9
sizeType: sizeType, // 可以指定是原圖還是壓縮圖,默認壓縮圖
sourceType: sourceType, // 可以指定來源是相冊還是相機,默認二者都有
success: function (res) {
// 返回選定照片的本地文件路徑列表,tempFilePath可以作為img標簽的src屬性顯示圖片
resolve(res.tempFilePaths);
},
fail:function(error){
reject(error)
}
})
});
},
上面代碼我們默認了,最多選{9}張,sizeType是{compressed}壓縮后的圖片,sourceType是{'album', 'camera'}相機和相冊。這樣我們就不用填任何參數,直接調用即可,就會使用默認的這些參數。
如果你需要定制參數,比如需要上傳原圖。你只要參對應參數即可,如:
chooseImage({sizeType:['original ']})
這樣就會覆蓋了默認的參數。
注意:參數格式必須數組格式,因為要wx.chooseImage的參數格式對應。
將本地資源上傳到開發者服務器,客戶端發起一個 HTTPS POST 請求,其中 content-type 為 multipart/form-data 。
如頁面通過 wx.chooseImage 等接口獲取到一個本地資源的臨時文件路徑后,可通過此接口將本地資源上傳到指定服務器。
OBJECT參數說明:
參數 | 類型 | 必填 | 說明 |
---|---|---|---|
url | String | 是 | 開發者服務器 url |
filePath | String | 是 | 要上傳文件資源的路徑 |
name | String | 是 | 文件對應的 key , 開發者在服務器端通過這個 key 可以獲取到文件二進制內容 |
header | Object | 否 | HTTP 請求 Header, header 中不能設置 Referer |
formData | Object | 否 | HTTP 請求中其他額外的 form data |
success | Function | 否 | 接口調用成功的回調函數 |
fail | Function | 否 | 接口調用失敗的回調函數 |
complete | Function | 否 | 接口調用結束的回調函數(調用成功、失敗都會執行) |
很明顯filePath為string,wx.uploadFile每次只能上傳一個文件。我們選了多張圖片,你卻只能一次上一個?
很明顯是小程序的框架還沒時間做到很完善。只是提供了基本的接口。其他豐富的就留回給開發者自己封裝開發。就像這篇文章。
所以這個的上傳是多文件上傳封裝。因為多文件上傳兼容單文件上傳,單文件上傳只需數組傳一個。上傳完拿結果數組的第一個即可。
uploadImage: function ({ files = [], name = 'file', formData = {}, header = {}, dir = '',url=config.uploadImageUrl}){
return new es6.Promise((resolve,reject)=>{
if (files && files instanceof Array && files.length>0){
var promiseList=[];
for (var i = 0; i < files.length;i++){
promiseList[i] = new es6.Promise((resolve, reject) => {
wx.uploadFile({
url: url + dir, //僅為示例,非真實的接口地址
filePath: files[i],
name: name,
formData: formData,
header: header,
success: function (res) {
resolve(res.data);
},
fail: function (error) {
reject(error);
}
})
});
}
es6.Promise.all(promiseList)
.then(function (result){
resolve(result);
})
.then(function(error){
reject(error);
})
}else{
reject('傳參有誤,請傳數組格式');
}
})
}
原理主要是每個請求按順序裝在一個數組里。然后用Promise.all批處理同時上傳,上傳后按照上傳時的順序返回結果。大家可以去看看es6的promise。
完整代碼如下:
import config from '../config.js'
import es6 from '../lib/es6-promise.min.js'
let upload={
chooseImage: function ({sizeType = ['compressed'], sourceType = ['album', 'camera'], count = 9}){
return new es6.Promise((resolve,reject)=>{
wx.chooseImage({
count: count, // 默認9
sizeType: sizeType, // 可以指定是原圖還是壓縮圖,默認壓縮圖
sourceType: sourceType, // 可以指定來源是相冊還是相機,默認二者都有
success: function (res) {
// 返回選定照片的本地文件路徑列表,tempFilePath可以作為img標簽的src屬性顯示圖片
resolve(res.tempFilePaths);
},
fail:function(error){
reject(error)
}
})
});
},
/**
* 以wx.request作為底層方法
* @param {arr} files 圖片url集合
* @param {String} url 圖片上傳接口地址
* @param {String} dir 上傳目錄地址
* @param {String} name 文件對應的 key , 開發者在服務器端通過這個 key 可以獲取到文件二進制內容
* @param {Object} header HTTP 請求 Header, header 中不能設置 Referer
* @param {Object} formData HTTP 請求中其他額外的 form data
*/
uploadImage: function ({ files = [], name = 'file', formData = {}, header = {}, dir = '',url=config.uploadImageUrl}){
return new es6.Promise((resolve,reject)=>{
if (files && files instanceof Array && files.length>0){
var promiseList=[];
for (var i = 0; i < files.length;i++){
promiseList[i] = new es6.Promise((resolve, reject) => {
wx.uploadFile({
url: url + dir, //僅為示例,非真實的接口地址
filePath: files[i],
name: name,
formData: formData,
header: header,
success: function (res) {
resolve(res.data);
},
fail: function (error) {
reject(error);
}
})
});
}
es6.Promise.all(promiseList)
.then(function (result){
resolve(result);
})
.then(function(error){
reject(error);
})
}else{
reject('傳參有誤,請傳數組格式');
}
})
}
}
export default upload;
現在app.js全局引入:
import Upload from './untils/upload.js'
App({
onLaunch: function () {
//......
},
Upload:Upload,
})
然后就可以在page的每個頁面使用了:
const app = getApp()
app.Page({
data: {
},
onLoad: function () {
app.Upload.chooseImage({ sizeType: ['original', 'compressed'], count:2}).then(function(files){
app.Upload.uploadImage({'files':files}).then(function(result){
console.log(result);
});
});
}
});
是不是方便多了。