所以我的标题可能没有多大意义,所以让我解释一下,在我可以转到浏览器URL并提供这样的获取文件请求之前,我正在将express与mongoose / MongoDB一起使用来上传/下载文件。 ,但是我想添加身份验证,并且由于我需要通过标头发送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秒钟以上的时间读取所有数据,然后提示使用下载并立即完成下载。但是,如果我删除了auth,然后仅通过浏览器通过URL进行身份验证,下载就会立即开始,并像往常一样显示chrome下载的进度。有什么方法可以通过axios
实现这种下载/流式传输功能吗?还是有某种不用axios
来发送令牌的方式,所以我可以完全避免使用令牌,而只是按常规方式进行操作?
答案 0 :(得分:0)
您可以将令牌作为查询而不是中间件(即http://localhost:3000/file-service/download?token=kjhdsjkf.sakhdh.asdkd
)作为查询传递,并在用户继续下载之前立即验证令牌