vue + element + express + 阿里云OSS
用到的第三方库: multer 、 multer-aliyun-oss
前端代码
利用 element ui 的上传组件
<el-upload
:action="uploadUrl"
:headers="getAuthHeaders()"
:show-file-list="false"
:on-success="handleSuccess"
>
<img v-if="model.icon" :src="model.icon" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
// action 上传图片的后端路由接口
// headers 上传的身份验证信息,一般为 token
// handleSuccess 上传成功后的回调函数
handleSuccess(res){
console.log(res)
//使用 该语句,图片不能显示,原因是因为 vue中的响应式系统造成的,因为 model.icon 开始并不在响应式系统中后加进去的
// this.model.icon = res.url
this.$set(this.model,'icon',res.url)
},
后端代码
采用 multer 组件 和 阿里云OSS 配合进行图片上传
const multer = require('multer');
const MAO = require('multer-aliyun-oss');
const upload = multer({
storage: MAO({
config: {
// 下面的私密信息应该放在 环境变量中,应该被git所忽略
region: secret.region,
accessKeyId: secret.accessKeyId,
accessKeySecret: secret.accessKeySecret,
bucket: secret.bucket
}
})
});
app.post('/admin/api/upload',authMiddleware,upload.single('file'),async (req,res) => {
const file = req.file
// file.url = `http://localhost:3000/uploads/${file.filename}`
res.send(file)
})
// authMiddleware 认证中间件 参考代码
module.exports = options => {
const jwt = require('jsonwebtoken');
const assert = require('http-assert')
const AdminUser = require('../models/AdminUser');
return async (req,res,next) => {
// 检验用户是否登陆
// const token = req.headers.authorization
// console.log(token)
// Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVmMzc1YWIwNGM4ZjZlNjg3MDA0NDM2NSIsImlhdCI6MTU5NzQ2Mzc0Nn0.Dbx2ngp9-vJYaOabwy_qJa6RlqeVRqmV2xEYBVHW0ZI
// 需要提取token 所以换一种写法 split(' ') 使用 空格 进行分割,分割完成后变成了数组,然后在使用pop() ,pop() 可以提取最后一个元素
const token = String(req.headers.authorization || '').split(' ').pop()
assert(token,401,'请提供 jwt-token')
// console.log(token)
// 接下来进行 token验证 看看这个token是不是 服务器颁发的 ,客户端有没有进行篡改
// decode(token) 对 token 进行解析,但是不会验证对错,不是很安全
// verify(参数一,参数二) 对于token 进行校验 ,参数一: 需要校验的token 参数二:我们原来设置的 秘钥
// 这里的req.app 和 app 是完全等同的
const { id } = jwt.verify(token,req.app.get('secret')) // 返回的数据的样式: { id: '5f375ab04c8f6e6870044365', iat: 1597463746 }
console.log(id)
assert(id,401,'无效的token')
// const user = await AdminUser.findById({id}) 如果想让 user 后续也能使用,需要将其挂载到req上
req.user = await AdminUser.findById(id)
// 上面步骤中的 token id req.user 其中任意一个不存在 都要做报错处理
// 这里采用 http-assert 包来进行处理
assert(req.user,401,'用户不存在')
await next()
}
}
本地存储
const multer = require('multer');
// 上传中间件 dest 表示上传到哪里去
const upload = multer({dest: __dirname + '/../../uploads'})
// 中间件 upload.single() 表示单个文件的上传,里面的字段名为 在network中上传接口中 FormData 字段名
app.post('/admin/api/upload',authMiddleware,upload.single('file'),async (req,res) => {
// express 本身处理不了上传的数据,这里采用 multer 来进行处理 ,上传的文件二进制可在 network接口中查看
const file = req.file
// 地址一定是 服务端 的地址 ,如果想让服务端的地址可以访问 一定需要配置路由
file.url = `http://localhost:3000/uploads/${file.filename}`
res.send(file)
})