当前状况:PC端有分片上传的接口,小程序里没有FormData 对象。
解决思路:自定义了一个FormData 对象(代码以及用法:https://www.jianshu.com/p/ece23dfd771a),传参有所区别,逻辑依然可以安卓web端的来。
在全局定义一个axios
Vue.prototype.$httpRequest2 = axios.create({
withCredentials: true,
crossDomain: true,
baseURL: '',
timeout: 6000
})
上传组件UploadFile.vue
引入
import FormData from '@/lib/wx-formdata/formData.js'
// 上传文件
uploadFile({
currentAssetId,
rootAssetId,
fileUploadUrl,
chunk,
chunkSize,
chunkTotal,
fileExt,
index,
rid,
md5
}) {
const that = this
// 进行上传
const start = (chunk - 1) * chunkSize
let end = start + chunkSize
let size = ''
const item = this.uploadFileList.find(it => it.rid === rid)
size = item.data.size
item.state = 'progress'
// 上传完成
if (start >= size) {
// 更改本地数据
this.uploadFilesChange({
currentAssetId: currentAssetId, // 文件id
chunk: chunkTotal, // 当前片
chunkTotal: chunkTotal,
state: 'success', // 状态
rid: rid, // 假数据id
md5State: 2 // 是否是假数据 1:假数据 2:真数据
})
return
}
// 最后一片
if (end > size) {
end = size
}
// 组装上传参数
let fileData = {}
fileData = item.data.fData
fileData = fileData.slice(start, end)
// 获取每一片的md5
this.spark.append(fileData)
const hexHash = this.spark.end(false)
const chunkMd5 = hexHash
const formData = new FormData()
// formData.append('currentAssetId', currentAssetId)
formData.appendFile('file', fileData, item.data.path)
const _data = formData.getData()
// 调用分片上传接口
that
.$httpRequest2({
url:
fileUploadUrl +
`Form?currentAssetId=${currentAssetId}&rootAssetId=${currentAssetId}&chunk=${chunk}&chunkSize=${chunkSize}&chunkTotal=${chunkTotal}&fileExt=${fileExt}&hash=${md5}&chunkHash=${chunkMd5}`,
method: 'POST',
timeout: 10000,
headers: {
'Content-Type': _data.contentType
// 注意,这里不能直接使用 'Content-Type': 'multipart/form-data',因为小程序中没有 FormData对象,所以需要自定义一个FormData对象
},
data: _data.buffer
})
.then(res => {
console.log('分片成功请求:', res, '第几片:', chunk)
// 存上传进度
that.uploadFilesChange({
currentAssetId: currentAssetId, // 文件id
chunk: chunk + 1, // 当前片
chunkTotal: chunkTotal,
state: 'success', // 状态
rid: rid, // 假数据id
md5State: 2 // 是否是假数据
})
that.uploadFile({
currentAssetId: currentAssetId,
rootAssetId: rootAssetId,
fileUploadUrl: fileUploadUrl,
chunk: chunk + 1,
chunkSize: chunkSize,
chunkTotal: chunkTotal,
fileExt: fileExt,
index: index,
rid: rid,
md5: md5
})
})
.catch(err => {
console.log('成功请求后,上传失败,重新上传:', err)
// 上传失败
that.uploadFilesChange({
currentAssetId: currentAssetId, // 文件id
chunk: chunk, // 当前片
chunkTotal: chunkTotal,
state: 'fail', // 状态
rid: rid, // 假数据id
md5State: 2 // 是否是假数据 1:假数据 2:真数据
})
that.uploadFile({
currentAssetId: currentAssetId,
rootAssetId: rootAssetId,
fileUploadUrl: fileUploadUrl,
chunk: chunk,
chunkSize: chunkSize,
chunkTotal: chunkTotal,
fileExt: fileExt,
index: index,
rid: rid,
md5: md5
})
wx.showToast({
title: res.msg,
icon: 'none'
})
})
}
注意,这里不能直接使用 'Content-Type': 'multipart/form-data',因为小程序中没有 FormData对象,所以需要自定义一个FormData对象。上面所使用的是自己封装的FormData对象。
用法:
这是结构:
components
|——UploadFile.vue
libs
|—— wx-formdata
|——formData.js
|——mimeType.js