【问题标题】:How to download/stream a file from a express + mongoDB server, using the browser download manager如何使用浏览器下载管理器从 express + mongoDB 服务器下载/流式传输文件
【发布时间】:2019-11-09 00:33:26
【问题描述】:

所以我的标题可能没有多大意义,所以让我解释一下,我正在使用 express 和 mongoose/MongoDB 来上传/下载文件,然后我可以转到浏览器 URL 并提供这样的获取文件请求,但是我想添加身份验证,并且由于我需要通过标头发送 JWT 令牌,因此我无法仅通过浏览器访问 URL,让我向您展示我目前所拥有的。

router.get('/file-service/download', auth, async (req, res) => {
  if (!req.user) {
    return res.status(401).send('Please authenticate');
  }

  try {
    const tempID = '5dc5f57a081263451cee80d4';

    const gfs = Grid(conn.db);

    gfs.findOne({ _id: tempID }, (err, file) => {
      //console.log("file", file);

      if (err) {
        return res.status(500).send(err);
      }

      res.set('Content-Type', file.contentType);
      res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');

      const readStream = gfs.createReadStream({
        _id: tempID
      });

      //console.log("grid", readStream);

      readStream.pipe(res);
    });
  } catch (e) {
    console.log(e);
    res.status(500).send(e);
  }
});

所以我过去常常去 localhost:3000/file-service/download,它会在 chrome 中开始下载,使用本机下载管理器,并显示进度,下载文件时你期望的一切,但是现在这是不可能的,所以我改为执行axios 请求,而不是像这样。

const config = {
  responseType: 'arraybuffer',
  headers: { Authorization: 'Bearer ' + 'jwtsecret' }
};

console.log('fetching download');

axios
  .get('http://' + currentURL + '/file-service/download', config)
  .then(response => {
    let blob = new Blob([response.data], { type: 'binary/octet-stream' });
    let link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = 'zip_test.zip';
    link.click();
  })
  .catch(err => {
    console.log(err);
  });

这是可行的,但是,它必须首先将整个文件加载到内存中,例如,我用一个 500mb 的文件进行测试,在我发出 axios 请求后,它需要 15 多秒才能完成获取所有数据,然后提示使用下载并立即完成。但是,如果我删除身份验证,并通过 URL 仅通过浏览器执行此操作,下载会立即开始并像往常一样显示 chrome 下载的进度。有没有办法用axios 实现这种相同的下载/流媒体功能?或者有什么方法可以在没有axios 的情况下发送令牌,这样我就可以完全避免它并以正常方式进行?

【问题讨论】:

    标签: javascript mongodb express axios


    【解决方案1】:

    您可以将令牌作为查询而不是中间件(即http://localhost:3000/file-service/download?token=kjhdsjkf.sakhdh.asdkd)传递,并在用户继续下载之前验证令牌

    【讨论】:

      猜你喜欢
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      • 2010-12-19
      • 2011-11-04
      相关资源
      最近更新 更多