目标
web端nodejs后端中转,将web端的文件上传至阿里云的oss
需要用到的技术
- 文件上传
- 将上传的文件暂存并且转存到阿里云oss上
要求
- 文件大小,格式限制
- 文件重新命名
- 文件位置存储数据
流程
根据上面分析之后,决定使用express的multer中间件,方便存储文件
需要安装express 和 multer 以及阿里云oss的node组件
npm install ali-oss
创建文件app.js
//添加引用
let OSS = require('ali-oss')
let express = require('express')
let app = express()
let multer = require('multer')
//允许跨域 视情况而定
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type,X-Token')
res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
res.header('Content-Type', 'application/json;charset=utf-8')
next()
})
//存储点 放置在和app.js同级的uploads目录下
let storage = multer.diskStorage({
destination: function (req, file, cb){
cb(null, './uploads')
},
//上传的文件以 时间(毫秒级) + 原来的名字命名
filename: function(req, file, cb) {
cb(null, Date.now() +'-'+ file.originalname)
}
})
//创建multer对象 设置文件大小上限为512kb fileFilter 对文件进行筛选 比如文件扩展名等
let upload = multer({
storage: storage,
limits: {fileSize:1024*512},
fileFilter: function(req, file, cb){
console.log(file)
cb(null, true)
}
})
//传输单个文件的配置
let uploadSingle = upload.single('single')
//post接口用上面的函数对象处理
app.post('/upload/single', (req, res) => {
uploadSingle(req, res, (err) => {
console.log(req.file)
if(err instanceof multer.MulterError) {
console.log(err)
res.json({
code: '405',
type: 'single',
error: 'multer error'
})
} else if(err) {
console.log(err)
res.json({
code: '402',
type: 'single',
error: 'unknown error'
})
} else {
put(req.file.filename)//这个put函数为向阿里云oss上传文件的函数 下面有
res.json({
code: '200',
type: 'single',
originalname: req.file.originalname
})
}
})
})
读一下阿里云oss的nodejs文档 查看其上传对象的方法
在app.js中继续添加
app.post(..../*省略的*/)
let client = new OSS({
region: 'oss-cn-hangzhou',//阿里云对象存储地域名
accessKeyId: '',//api接口id
accessKeySecret: '',//api接口密码
})
client.useBucket('xxx')//使用的存储桶名
//向存储桶中添加文件的接口
async function put(filename) {
try {
let result = await client.put('test/' + filename,'uploads/' + filename)
console.log(result)//在此处记录 url name 等信息
} catch (err) {
console.log(err)
}
}
//监听端口 接收post信息
let server = app.listen(2333, function() {
const port = server.address().port
console.log('监听端口:%s', port)
})
前端上传文件
前端用了非常简单的方式上传文件,当然如果是FormData,使用ajax也能发送
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>upload</title>
</head>
<body>
<form action="http://localhost:2333/upload/single" method='post' enctype='multipart/form-data'>
<input type="file" name='single'>
<input type="submit">
</form>
</body>
</html>
表现就像下面一样
按提交之后
然后就能在存储桶中看到这两个文件了(我提交了俩个):
注意
- 使用multer上传文件限制上传文件大小的时候,只有文件流到达限定的值它才能知道这个文件超过了最大的文件大小。比如设定了50mb的上传上限,那么如果你上传一个100mb的文件,最开始的时候并不会报错,而是上传一定的时间(即文件上传了50mb)之后才会报出文件大小超过限制的错误 ,目前来说没有比较完美的解决方案(至少我没看到)
- 除此之外,上传的文件后续应该将url存入数据库 方便调用,鉴于oss对象存储的下载速度很快而且不会占用云服务器带宽,可以配合低带宽的服务器让网站访问更快速。