后台把文件上传做成了三段
- 发送文件名称用来请求 presignedUrl 和 filePath
- 通过 presignedUrl 上传文件
- 将 filePath 发送到后台,完成数据库对文件的位置的存储,并返回文件地址以及文件Id
首先,上传文件名
async function getPresignedUrl(fileName) {
const result = await axios({
url: `/getPresignedUrl`,
method: 'post',
data: {
fileName
}
});
return result.data;
}
这个请求会返回两个内容,presignedUrl 是一个带签名的地址,类似于 token,确保时效内有权限可以上传文件,另外一个就是 filePath,这个是文件路径,先不用管,等下会用到。
拿到了 presignedUrl 之后,我们可以通过这个带有签名的地址上传文件
async function uploadMinIO(presignedUrl, file) {
return await fetch(preSignedUrl, {
method: 'PUT',
body: file
});
}
因为这个接口只会返回成功或者失败,所以只需要直接返回,不需要过多处理。
当然,也有可能会出现一个问题,上传图片的时候返回的数据里面的 code 是 200,但是上传其他类型的文件的时候返回的是 400,这就需要后台去修改了,请相信这不是你的问题。
另外有一点需要说明,body 就是 file,而不是通过 formData 的形式去上传文件,他需要的只是文件。
还有一件事,这里用了官方推荐的 fetch,也是因为上面的原因。
好了,现在到第三步了,也就是用到 filePath 的一步,上传文件路径(filePath)到后台去。
async function postFilePath(filePath) {
return await axios({
url: `/postFilePath`,
method: 'post',
data: {
filePath
}
});
}
后台会返回 id 和 url,我们直接用这个内容就可以去做其他的事情了,比如将这个 url 存储成用户头像,不过在这之前要先将上面三个内容封装成一个函数来使用好一点:
async function getPresignedUrl(fileName) {
const result = await axios({
url: `/getPresignedUrl`,
method: 'post',
data: {
fileName
}
});
return result.data;
}
async function uploadMinIO(presignedUrl, file) {
return await fetch(preSignedUrl, {
method: 'PUT',
body: file
});
}
async function postFilePath(filePath) {
return await axios({
url: `/postFilePath`,
method: 'post',
data: {
filePath
}
});
}
async function getFileMsg(file) {
// 获取 minIO 上传地址、文件路径
const {preSignedUrl, filePath} = await getPreesignedUrl(file.name)
// 等待上传
await uploadMinIO(preSignedUrl, file)
// 获取url 和 fileId
return await postFilePath(filePath)
}
现在封装好了,就可以实现头像上传了:
async function submit() {
const avatar = document.querySelector('input[type="file"]').files[0]
consst {fileId, url} = await getFileMsg(avatar)
await axios({
url: '/submit/form',
method: 'post',
data: {
fileUrl: url,
fileId: fileId,
// ...other data
}
})
}
大功告成。
敬礼 (^^ゞ