vue做个后台管理,用微信提供的http操作云储存上传文件会出现跨域问题,我只想搭个前端就能直接上传到云文件,不想再搭个后台中转。
换个思路,云函数是可以直接请求的,云函数里是可以直接上传图片到云文件的
由上可得 可以把图片数据传到云函数在云函数中上传图片
然而 测试发现云函数调用时有最大数据限制,大概十几kb就报错了,这肯定时不行的
但是
数据库新增是可以直接操作的,
来一波骚操作,先把图片数据转换成base64的字符串上传到云数据库,把_id传给云函数,让云函数从数据库中取出图片的数据,转换成
new Buffer(base64Data, 'base64')
哈哈哈哈哈哈哈哈哈哈哈,完美上传图片
然而事情并没有那么简单~~
上传到云数据库时也有数据大小限制的
经过测试 base64字符串在500000字符长度是可以的(大概400kb)
在600000字符长度就会报错,
所以我们还要对上传的图片数据做分批上传
以上测试都没有错误截图了,只有已经可以完美上传的代码(请勿完全复制,根据你项目实际情况修改)
export function add(token, datastr) {
const params = {
"env": envid,
"query": "db.collection(\"testadd\").add({data:"+ datastr + "})",
}
// console.log("==params==" + JSON.stringify(params))
var url = 'api/tcb/databaseadd?access_token=' + token;
return request({
url: url,
method: 'POST',
data: params
})
}
addObj({ commit },param) {
return new Promise((resolve, reject) => {
var accessToken=state.token
if(accessToken==null){
accessToken=getToken()
}
add(accessToken,JSON.stringify(param)).then(response => {
//
// console.log('上传数据返回结果',response)
resolve(response)
if(response.errcode == 0){
// if(response.data[0] != null){
// resolve(JSON.parse(response.data[0]))
// }else{
// resolve(null)
// }
}
}).catch(error => {
reject(error)
})
})
},
//这是html中的
<input type="file" @change="handleChange" ref="fileInput1" accept="image/*">
//input上传文件的回调
handleChange(info) {
const file = this.$refs.fileInput1.files[0]
const fr = new FileReader()
var self = this
fr.onload = (e) => {
try {
console.log('file', fr)
// self.imgData = fr.result
self.imgData = {type:"Buffer", data: fr.result}
} catch (error) {
self.$message.error(`${file.name} 打开失败`);
}
}
fr.readAsDataURL(file)
info.target.value= ""
},
//点击确定上传按钮回调
onModalOk(){
var imgData = self.imgData.data
var splitCount = 500000
//长度大于一定时就要分断上传
// if(imgData.length > splitCount){
// imgData = imgData.substring(0, splitCount)
// }
var count = Math.ceil(imgData.length / splitCount) //要上传的次数
var hasAdd = 0
var idList = []
for (let index = 0; index < count; index++) {
const subData = imgData.substring(splitCount * index, splitCount * (index + 1));
self.$store
.dispatch("user/addObj", {name: 'testName.png', fileStream: subData, index: index})
.then(response => {
hasAdd += 1
idList.push(response.id_list[0])
console.log('当前hasAdd', idList, hasAdd, count)
if(hasAdd == count){
self.$store
.dispatch("user/updateImgObj", {id: idList})
.then(response2 => {
self.listLoading = false
console.log('关闭返回的结果2', response2)
}).catch(error => {
self.listLoading = false
self.$message.error('上传失败');
})
}
}).catch(error => {
self.listLoading = false
self.$message.error('上传失败');
})
}
}
然后是云函数中的代码:
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const _ = db.command
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
var arr = []
for (var i = 0; i < event.id.length; i++){
var data = await db.collection("testadd").doc(event.id[i]).get()
arr.push(data.data)
}
arr.sort(function(a, b){
return a.index - b.index
})
var base64Data = ''
for (var i = 0; i < arr.length; i++){
base64Data += arr[i].fileStream
}
// return data
base64Data = base64Data.replace(/^data:image\/\w+;base64,/, "");
var result = await cloud.uploadFile({
cloudPath: arr[0].name,
fileContent: new Buffer(base64Data, 'base64') //{ type: 'Buffer', data: data.fileStream},
})
// var result = {}
// result.data = base64Data'
//上传完成后删除数据库中的数据
for (var i = 0; i < event.id.length; i++) {
await db.collection("testadd").doc(event.id[i]).remove()
}
return result
}
研究了一天,上传图片这块微信的文档里只是简单说了上传格式,却没有例子,一次次尝试才测试出什么样的格式存到云函数中是有效的图片,分享给广大有需求的程序员,减少需要研究花费的时间
你在调用云函数的时候不也要发请求?这不还是一样会跨域
问下楼主,怎样直接在前端上传markdown文件?
不错,点赞