vue+element+koa 上传/下载文件
file.js
const Koa = require('koa')
const app = new Koa()
const koaBody = require('koa-body') // 将请求报文和响应报文转化成可读数据
const Router = require('koa-router') // 路由中间件
const send = require('koa-send') // 将静态文件转换成文件流,提供下载功能
const cors = require('koa2-cors') // 跨域
const fs = require('fs') // 文件系统中间价
const router = new Router()
router.get('/', async ctx => {
ctx.body = '欢迎'
})
// 下载
router.get('/download', async ctx => {
const path = '/static/抖音运营sop整理.pdf'
ctx.attachment(path)
await send(ctx, path)
})
// 上传
router.post('/upload', async ctx => {
// 文件流在ctx.request.files.file中,附带参数在ctx.request.body中
console.log(ctx.request.files.file, ctx.request.body)
const file = ctx.request.files.file
const reader = fs.createReadStream(file.path)
const upStream = fs.createWriteStream(`./static/${file.name}`)
reader.pipe(upStream)
return ctx.body = { 'msg': '上传成功', 'type': ctx.request.body.type }
})
app
.use(koaBody({
multipart: true, // 允许上传或下载文件
formidable: {
maxFileSize: 200*1024*1024 // 限制上传或下载的文件的大小
}
}))
.use(cors({
origin: function(ctx) {
// 可以放行/限制某些域名请求的跨域
if (ctx.url === '/test') {
return false;
}
return '*';
},
exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
maxAge: 5,
credentials: true,
allowMethods: ['GET', 'POST', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}))
.use(router.routes())
.use(router.allowedMethods())
app.listen(3001, () => {
console.log('koa is listening in 3001')
})
file.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"/>
<title>文件系统</title>
</head>
<body>
<div id="app">
<el-button @click="download">下载文件</el-button>
<el-upload
class="upload-demo"
action="http://localhost:3001/upload"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:before-upload="beforeUpload"
:on-success="handleSuccess"
:http-request="upload"
:data="additionalData"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
fileList: [],
additionalData: { type: 'init' }
}
},
methods: {
download() {
window.open('http://localhost:3001/download', 'self')
},
upload(e) {
console.log(e)
let formData = new FormData()
formData.append('file', e.file)
formData.append('type', 'test')
axios({
method: 'post',
url: 'http://localhost:3001/upload',
headers: {
'Content-Type': 'multipart/form-data'
},
data: formData
}).then(res => {
console.log('res', res)
})
},
beforeUpload(file) {
this.additionalData = { 'type': 'test' }
return new Promise(resovle => {
this.$nextTick(() => {
resovle(true)
})
})
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${ file.name }?`);
},
handleSuccess(res, file, fileList) {
console.log('上传成功:', res)
}
}
})
</script>
</html>