7

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

应用程序.js

const Koa = require('koa')
const router = require('./router')

const app = new Koa()

app.use(router.routes())
app.use(router.allowedMethods())

app.listen(3000)

路由器.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

客户端.js

const { fetch } = window;

const request = {
  method: 'POST',
  body: JSON.stringify({ fake: 'data' })
}

// Make the POST request
fetch('/generate', request)

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

4

3 回答 3

6

您应该在正文中设置文件流并将 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>
于 2016-10-06T12:29:04.577 回答
5

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

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

在客户端,您需要在通过发布请求接收文件内容时创建并触发下载。将此代码放入请求回调中

fetch('/generate', request)
  .then(res => { return res.text() })
  .then(content => {

    uriContent = "data:application/octet-stream," + encodeURIComponent(content);

    newWindow = window.open(uriContent, 'somefile');

  });
于 2016-09-30T21:21:33.900 回答
0

使用标签下载可以实现相同的功能。我更喜欢这个。它可以在没有 JS 的情况下工作,但不能在 safari 中使用。

<!DOCTYPE html>
<html>
<body>

<p>Click on the w3schools logo to download the image:<p>

<a href="http://www.w3schools.com/images/myw3schoolsimage.jpg" download>
  <img border="0" src="http://www.w3schools.com/images/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

于 2016-10-07T19:18:30.003 回答