上传之前当然要选上传的文件。
小程序的上传业务是这个样的
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);
});
});
}
});
是不是方便多了。