naive-ui icon indicating copy to clipboard operation
naive-ui copied to clipboard

在n-uploader的on-download回调中,可以更新文件的下载URL

Open casatwy opened this issue 1 year ago • 2 comments

问题的清晰而简明的描述

  1. 当文件保存在阿里云OSS中时,需要下载文件的时候,需要向OSS获取一个下载URL,但这个下载URL会有有效时长限制。
  2. 用户通过n-uploader上传文件之后,不见得就是会去立刻下载的。

所以用户如果要下载刚刚自己上传的文件的话,理论上可以采取两种方式: 方案1. 给每个文件都向OSS获取一个下载URL,然后把这个URL的有效期设置得非常长,例如1小时。 方案2. 每次点击下载按钮(n-uploader的file list自带的那个下载按钮)的时候,向OSS获取一次下载URL,然后下载。

方案1的问题在于:

  1. 因为用户不见得每次都会下载自己上传的文件,因此给每个文件都申请一次OSS下载URL是多余的。
  2. 把URL的有效期设置得非常长或者索性不设置有效期,那么就会导致文件下载URL滥用的问题,坏人可能会频繁下载文件,导致OSS费用上升。

所以认为方案2会更好。

建议的解决方案

当前n-uploader有on-download方法:

async function handleDownload(params) {
/*
params is:
{
      "id": "b534e33b",
      "name": "article2.png",
      "percentage": 100,
      "status": "finished",
      "url": null,
      "file": {},
      "thumbnailUrl": null,
      "type": "image/png",
      "fullPath": "/1.png",
      "batchId": "364d966b"
}
*/
}

我期望能够修改params的url字段,这样的话就能在点击下载按钮的时候申请OSS的下载URL了,就像下面这样:

async function handleDownload(params) {
    // 根据map找到真正的文件id
    let fileID = uploaderIDMap[params.id]

    // 拿着文件id去OSS获取下载URL
    let fetchedURL = await getOSSURL(fileID)

    // 将真正的URL赋值给这个params
    params.url = fetchedURL
    
    return true // 如果不能直接将params刚刚更新的URL属性用上的话,换成下面这句也可以
    renturn params // 此时的params的url属性就不是null了,是刚刚赋值过的fetchedURL

    return false // 这时候表示获取OSS URL失败了,所以return false,那么就还是按照文档之前的逻辑照旧执行就好了

/*
文档内容:
点击文件下载按钮的回调函数,返回 false、Promise resolve false、Promise rejected 时会取消本次下载
*/

}

备选方案

No response

附加上下文

No response

验证

  • [X] 阅读 贡献指南
  • [X] 阅读 文档
  • [X] 检查是否已经存在请求相同功能的问题,以避免创建重复的问题。

casatwy avatar May 14 '24 06:05 casatwy

另外还有一个方案3:

async function handleDownload(params) {
    // 根据map找到真正的文件id
    let fileID = uploaderIDMap[params.id]

    // 拿着文件id去OSS获取下载URL
    let fetchedURL = await getOSSURL(fileID)

    // 拿到fetchedURL之后,我自己创建一个a标签,自己触发一次下载,然后再把这个a标签删掉
    const link = document.createElement('a')
    link.href = fetchedURL
    link.style.display = "none"
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)

    return false // 取消n-uploader的下载事件
}

上面这种做法虽然有效,但我感觉有点low.

casatwy avatar May 14 '24 07:05 casatwy

同样的情况,我就是用的方案3

yuanhongyu123 avatar May 15 '24 06:05 yuanhongyu123