【问题标题】:node app download file from gcloud storage to client节点应用程序从 gcloud 存储下载文件到客户端
【发布时间】:2019-05-16 01:33:46
【问题描述】:

似乎这应该有某种固定答案,但我找不到任何东西。

场景是这样的:

  • 我有一个列出要下载的文件的网页
  • 文件位于 gcloud 存储中
  • 我有一个节点服务器 (express) 应用程序可以访问 gcloud 并获取文件。

网页js长这样:

<script>
  function downloadFile(client, fn) {
    var x=new XMLHttpRequest();
      x.open("GET", "https://<domain>/fetch/" + client + '/' + fn, true);
      x.responseType = 'blob';
      x.onload=function(e){download(x.response, fn, "<content-type>" ); }
      x.send();
  }
</script>

它使用所需的 fetch args 直接向服务器执行 XMLHttpRequest()。

nodejs的相关部分是这样的:

app.get('/fetch/:client/:filename', async function(req,rsp) {
  try {
    const storage = new Storage();
    const fileLoc = req.params.client + '/' + req.params.filename

    const options = {
      destination: './' + req.params.filename,
    };

    // Downloads the file
    let file = await storage
      .bucket('<bucket-name>')
      .file(fileLoc)

    let rstream = await file.createReadStream()
    .on("error", (err) => {
      console.log(" --> rstream error: " + err)
    })
    .on("response", (strRsp) => {
      console.log(' --> response received, sending headers.')
      rsp.setHeader('Content-Length', strRsp.headers['content-length'])
      rsp.setHeader('Content-Type', strRsp.headers['content-type'])
      rsp.header('Content-Disposition', 'attachment; filename=' + req.params.filename)
    })
    .on("end", () => {
      console.log(' --> end received.')
      rsp.status(200).end()
      return true
    })
    .pipe(rsp)

  } catch(err) {
    console.log('download error: ' + err)
    rsp.status(400).send('failed') 
  } 
});

问题是它可以工作,但它会在打开另存为对话框之前(静默)下载整个文件。

有没有办法在下载前打开保存对话框? (也许我需要在客户端做'content-disposition'标头......?)

除此之外,有没有办法将进度反映回网页 js,以便我可以打开一个对话框并显示进度,也许还有一个取消按钮,直到它完成并显示另存为对话框?

【问题讨论】:

    标签: node.js google-cloud-storage


    【解决方案1】:

    好的,我选择了后一个答案。执行以下操作:

    • 根据下载请求,弹出加载对话框,其中包含有关下载的信息。
    • 向 XMLHttpRequest 实例注册进度回调
    • 在对话框中显示进度信息
    • 对话框有一个“取消”按钮,它在 XMLHttpRequest 实例上调用“abort()”
    • 在完成(或中止)时更新对话框,然后通过超时关闭它。

    【讨论】:

      猜你喜欢
      • 2018-04-25
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 2013-10-27
      • 2017-09-06
      • 2019-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多