8-1 上传图片需求分析
- 用户头像
- 封面图片
- 问题和回答中的图片
- 话题图片
上传图片的功能点
- 基础功能:上传图片、生成图片链接
- 附加功能:限制上传图片的大小与类型、生成高中低分辨率的图片链接、生成 CDN
上传图片的技术方案
- 阿里云 OSS 等云服务,推荐在生产环境下使用(收费)
- 直接上传到服务器,不推荐在生产环境下使用(对于分布式不友好,而且容易丢失资源)
8-2 使用 koa-body 中间件获取上传的文件
- 安装 koa-body,替换 koa-bodyparser
- 设置图片上传目录
- 使用postman 上传文件
npm i koa-body --save
npm uninstall koa-bodyparser --save
koa-body不止支持json、form,还支持文件格式。
app/index.js
const koabody = require('koa-body')
const path = require('path')
...
app.use(koabody({
multipart: true, // 启用文件
formidable: {
uploadDir: path.join(__dirname,'/public/uploads'), // 上传目录
keepExtensions: true // 保留拓展名
}
}))
controllers/home.js
class HomeCtl {
index (ctx) {
ctx.body = '<h1>这是主页</h1>'
}
upload (ctx) {
const file = ctx.request.files.file
ctx.body = { path: file.path}
}
}
module.exports = new HomeCtl()
routes/home.js
const Router = require('koa-router')
const router = new Router()
const {index, upload} = require('../controllers/home')
router.get('/', index)
router.post('/upload',upload)
module.exports = router
8-3 使用 koa-static 中间件生成图片链接
- 安装 koa-static
此中间件帮助我们生成一个静态服务,指定了一个文件夹,文件夹下所有文件可通过http服务访问 - 设置静态文件目录
- 生成图片链接
npm i koa-static --save
app/index.js
const koaStatic = require('koa-static')
...
app.use(koaStatic(path.join(__dirname,'public')))
生成图片链接 controllers/home.js
const path = require('path')
class HomeCtl {
index (ctx) {
ctx.body = '<h1>这是主页</h1>'
}
upload (ctx) {
const file = ctx.request.files.file
const basename =path.basename(file.path)
ctx.body = { url: `${ctx.origin}/uploads/${basename}`}
}
}
module.exports = new HomeCtl()
- 通过path.basename可以获取文件的basename,即upload_73fa113c97a8c67e9a0e54e03584b895.png。
- 通过ctx.origin可以获取当前主机加端口,即localhost:3000
8-4 编写前端页面上传文件
- 编写上传文件的前端页面
- 与后端接口联调测试
uploads/upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>上传文件</title>
</head>
<body>
<form action="/upload" enctype="multipart/form-data" method="POST">
<input type="file" name="file">
<button type="submit">上传</button>
</form>
</body>
</html>
也可以修改下面指定只能上传图片:
<input type="file" name="file" accept="image/*">