我有一个反应前端和一个nodejs / express后端。后端可以通过受保护的路径提供文件(下载):
GET /api/file/:id
当前端想要开始文件下载时,它会使用此代码向此端点发送请求(Authorization
标头设置为有效token
):
axios.get(`${apiURL}/file/${id}`)
.then(file => {
...
})
后端响应此代码:
router.get('/file/:id', requireAuth, = (req, res, next) => {
...
res.set('Content-Type', 'application/pdf');
res.download(file.path, file.filename);
};);
这很好用:下载开始,二进制数据出现在file
调用的.then()
案例的axios
对象中。
我的问题:
我没有下载完整的文件,而是希望在文件下载开始之前将文件传递给浏览器,以便浏览器像通常的浏览器触发下载一样处理下载,浏览器提示它应该下载或下载显示文件。怎么能这样做??
解决方案:
感谢@FakeRainBrigand提示我通过请求参数向路线添加了基于令牌的授权(使用护照策略):
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromExtractors([
ExtractJwt.fromHeader('authorization'),
ExtractJwt.fromUrlQueryParameter('token'),
]),
secretOrKey: secretKey,
};
现在我可以将下载直接传递给浏览器来处理它:
window.location.href = `${apiURL}/file/${_id}?token=${token}`;
答案 0 :(得分:1)
Authorization标头会在此处引发问题。您应该使用cookie,至少对于此功能。否则,您必须在URL中包含一个令牌。
这两个解决方案是window.open
以响应事件或导航到网址(例如location.href = '...'
)。
至少在某些浏览器中,尽管您更改了位置,但在文件下载时它们实际上并不会导航。