最近关于minio遇到的问题

622 阅读2分钟

后台把文件上传做成了三段

  1. 发送文件名称用来请求 presignedUrl 和 filePath
  2. 通过 presignedUrl 上传文件
  3. 将 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
    }
  })
}

  

大功告成。

敬礼 (^^ゞ