核心代码
const upload = require ( 'koa-multer' ) ( { dest: './public/images' } ) ;
router. post ( '/upload' , upload. single ( 'file' ) , ctx=> { console. log ( 'file' , ctx. req. file) ; console. log ( 'body' , ctx. req. body) ; ctx. body = '上传成功' ;
} )
目录结构如下
基本思路
1.通过浏览器访问url: http://localhost:3000/upload 2.服务器(koa)监听到对应的路由,调用路由处理函数 3.使用nunjucks模板引擎进行渲染,并返回给浏览器 4.浏览器渲染完毕后显示出来. 5.点击上传文件->上传 6.服务端监听到上传的POST请求,进行相应的处理并将处理结果返回给前端
总体代码
const koa = require ( 'koa' ) ;
const app = new koa ( ) ;
const router = new require ( 'koa-router' ) ( ) ;
const multer = require ( 'koa-multer' ) ;
const nunjucks = require ( 'koa-nunjucks-2' ) ;
const path = require ( 'path' ) ;
const fs = require ( 'fs' ) ;
app. use ( nunjucks ( { ext: 'html' , path: __dirname, nunjucksConfig: { trimBlocks: true }
} ) ) ;
const upload = multer ( { dest: 'uploads/'
} ) ; const types = upload. single ( 'avatar' ) ;
router. get ( '/upload' , async ( ctx, next) => { await ctx. render ( 'upload' )
} ) router. post ( '/profile' , types, async ( ctx, next) => { const { originalname, path: out_path, mimetype} = ctx. req. file; let newName = out_path + path. parse ( originalname) . ext; let err = fs. renameSync ( out_path, newName) ; let result; if ( err) { result = JSON . stringify ( err) ; } else { result = `<h1>upload success</h1>` ; } ctx. body = result;
} ) ; app. use ( router. routes ( ) ) ; app. listen ( 3000 , async ( ) => { console. log ( 'Server is running at http://localhost:3000' ) ;
} )
<!DOCTYPE html>
< html lang = " en" > < head> < meta charset = " UTF-8" > < title> Document</ title>
</ head> < body> < form method = " post" action = " /profile" enctype = " multipart/form-data" > 选择图片: < input name = " avatar" id = " upfile" type = " file" /> < input type = " submit" value = " 提交" /> </ form>
</ body> </ html>
Element-ui组件(前端)文件上传
<!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" > < script src = " https://cdn.jsdelivr.net/npm/vue/dist/vue.js" > </ script> < script src = " https://unpkg.com/element-ui/lib/index.js" > </ script> < link rel = " stylesheet" href = " https://unpkg.com/element-ui/lib/theme-chalk/index.css" > < style> .avatar-uploader .el-upload { border : 1px dashed #d9d9d9; border-radius : 6px; cursor : pointer; position : relative; } .avatar-uploader-icon { font-size : 28px; color : #8c939d; width : 178px; height : 178px; line-height : 178px; text-align : center; } .avatar { width : 178px; height : 178px; display : block; } </ style> < title> 文件上传</ title>
</ head>
< body> < div id = " app" > < el-uploadclass = " avatar-uploader" action = " http://localhost:3000/users/upload" :show-file-list = " false" :on-success = " handleAvatarSuccess" :before-upload = " beforeAvatarUpload" > < img v-if = " imageUrl" :src = " imageUrl" class = " avatar" /> < i v-else class = " el-icon-plus avatar-uploader-icon" > </ i> </ el-upload> </ div> < script> var app = new Vue ( { el: "#app" , data ( ) { return { imageUrl: "" } ; } , methods: { handleAvatarSuccess ( res, file) { this . $message. success ( "上传头像成功" ) ; this . imageUrl = URL . createObjectURL ( file. raw) ; } , beforeAvatarUpload ( file) { const isJPG = file. type === 'image/jpeg' ; const isLt2M = file. size / 1024 / 1024 < 2 ; if ( ! isJPG) { this . $message. error ( "上传头像图片只能是 JPG 格式!" ) ; } if ( ! isLt2M) { this . $message. error ( "上传头像图片大小不能超过 2MB!" ) ; } return isJPG && isLt2M; } } , } ) </ script>
</ body>
</ html>