前言
最近在用express重写博客后端(因为之前的代码实在是太乱了),身边有个专门学后端的同学问我,你图片资源都是保存在哪里的?我直接给他看了我的项目目录,说道:“保存在express的静态web目录下啊”。如下。
然后他就开始了吐槽,并且给我转发了一篇名为《无语!刚来的实习生竟然把文件上传到本地服务器中》的文章。其实也有道理,如果服务器离用户太远的话,获取资源的速度太慢。所以我考虑将这些资源在请求的时候存储到七牛云上,并且写这篇文章,记录一下。
步骤1:创建七牛云存储空间
创建完成之后,会给你一个测试外链域名,我们可以上传文件
并且通过这个外链域名来获取文件
步骤2:修改外链域名为备案域名
首先创建绑定域名
其余配置几乎不需要改,这里的域名是已经备案的域名,如果是存图片文件的话,一般将test前缀改成img
添加成功之后进入域名管理,新添加的域名状态为成功时才可以使用,并且刚添加的域名是未配置的,我们需要配置CNAME
鼠标移入未配置,复制对应的地址,进入域名服务器进行配置(我是腾讯云)。如下,记录值是刚才赋值的地址。
配置完之后回到七牛云域名管理,刷新看对应的域名是否是已配置状态
如果是已配置,并且状态是成功,那么回到存储空间的文件管理中,外链域名会新增一条(就是刚才添加的那条),选中它即可。
步骤3:使用multer和qiniu这两个库实现上传文件
npm install multer qiniu
请求入口如下
- auth是我自己写的登录认证中间件,可以不用管
- 第二个是multer的使用方法,这里的作用是将req.body中携带的files对应的文件解析,保存在req.file中
- Upload中间件是实现上传的中间件
请求如下,title是文章名,categoryName是分类名,用于实现开头的分文件管理图片的效果
Upload中间件的实现
在使用qiniu这个库之前,我们需要做一些前置操作:创建配置信息。
AK和SK用于登录并且获取操作七牛云的权限,bucket是对应的存储空间的名字,AK和SK的获取方法在下图。
Upload中间件代码如下
//传入AK和SK
const mac = new qiniu.auth.digest.Mac(qiniuConfig.AK, qiniuConfig.SK);
const config = new qiniu.conf.Config();
config.zone = qiniu.zone.Zone_z2; //选择地区,这取决于存储空间所在的区域
const putPolicy = new qiniu.rs.PutPolicy({
scope: qiniuConfig.bucket, //存储空间名字
expires: 7200,
callbackBodyType: "application/json",
});
const uploadToken = putPolicy.uploadToken(mac);
const formUploader = new qiniu.form_up.FormUploader(config);
const putExtra = new qiniu.form_up.PutExtra();
let Upload = (req, res) => {
//获取文章名 和 分类名
const { title, categoryName } = req.body;
const buffer = req.file.buffer; // 获取buffer
formUploader.put(
uploadToken,
`img/${categoryName}/${title}/${req.file.originalname}`, //保存的路径
buffer, //传入文件buffer
putExtra,
function (respErr, respBody, respInfo) { //回调函数
if (respErr) {
throw respErr;
}
if (respInfo.statusCode == 200) {
res.send(respBody);
} else {
res.send({
status: respInfo.statusCode,
respBody,
});
}
}
);
};
对上面代码的部分解释
- 关于config.zone的值,需要查看存储空间的区域,选择对应的值
- 因为我需要做到分文件存储/img/分类名/文章名/对应的图片文件,所以需要在请求中传入title和categoryName。实现的效果如下。
另外,通过上图可以看到,返回的信息中key值是对应的文件目录,我们只需要拼接上外链域名就是图片地址啦。