Загрузите файл из POST-запроса в Koa
Я пытаюсь запустить загрузку из обработчика запросов POST в Koa с помощью koa-router
. По сути, я пытаюсь сделать что-то вроде этого:
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)
маршрутизатор.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 отправляется, ничего не происходит. Я не получаю никаких ошибок в консоли сервера или консоли браузера. Любая помощь будет оценена!
3 ответов
Вы можете попробовать использовать https://github.com/koajs/send
router.post('/generate', function * (next) {
yield send(this, 'file.txt');
});
и на стороне клиента вам нужно будет создать и запустить загрузку при получении содержимого файла через post-запрос. Поместите этот код в запрос обратного вызова
fetch('/generate', request)
.then(res => { return res.text() })
.then(content => {
uriContent = "data:application/octet-stream," + encodeURIComponent(content);
newWindow = window.open(uriContent, 'somefile');
});
вы должны установить поток файлов в теле и отправить 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>
та же функциональность может быть достигнута с помощью загрузки тега.Я предпочитаю это.Он работает без 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>