“ 最近在做一个 demo 测试,会涉及到图片存储的问题。由于之前一直用的是阿里云相关的服务,所以在这里讲解的也是阿里云官方提供的OSS服务。”
01
—
为什么会考虑使用阿里云 OSS 来存储图片
最开始想到比较简单的方法:用图床去存储图片,但是这个图床有一个问题在于它是三方的,安全性和稳定性未知。
说到图床我举一个例子,让我印象很深刻的是之前自己搭建的网站,里面涉及到很多的图片就是用的三方图床去存储的,后面想要再看看相关的图片,发现大部分图片都已经失效无法访问了。所以用三方图床去存储重要的图片,这种风险是很大,结合多个地方调研后还是考虑基于阿里云 OSS 服务自己维护一套。
02
—
阿里云服务中如何创建?
一、准备工作
(1)首先在搜索框中搜索“对象存储OSS”,如果你首次是没有开通过的话,会提示让你开通 ,接着点击立即开通即可。
(2)接着由于上传图片默认是按照按量计费的,这种不划算,我们可以去购买资源包,找到:对象存储OSS -> 资源用量 -> 资源包管理 -> 购买资源包
在这里我分别购买了两个包:“标准存储 - 同城冗余”、下行流量,在下方官方也给了对应的解释。
- 标准存储 - 同城冗余:同城冗余存储可提供更高的可用性保障,采用多可用区(AZ)冗余机制,将用户的数据分散存放在同一地域的多个可用区,即使某个可用区不可用时,仍然能够保障数据的正常访问;
- 下行流量:可用于抵扣通过互联网浏览或下载 OSS 数据所产生的外网流出流量。
二、创建与存储空间 Bucket
1. 首先找到对象存储 OSS 下的 Bucket 列表,接着点击创建 Bucket,如下图所示:
2. 接着在创建 Bucket 时,按照下面的截图来选择,当然也可以按照你自己的需求来进行选择
后面都选择默认的值即可,接着就点击完成创建。
注意:在这里我想要说一下读写权限,由于默认是阻止公共访问的且无法关闭,所以读写权限是私有的,然后这里如果是私有的话,后续我们想要直接访问对应的链接地址会提示不能访问的情况,针对于这个问题我在后续也有解决方式。
3. 在创建完成之后,我们可以看到对应 Bucket 列表里面就有我们刚创建好的 Bucket,然后点击对应 Bucket 的名称,可以进入到对应的详情里,点击概览,就可以看到对应的访问端口的信息,这个是后续需要在开发中用到的信息
03
—
创建 RAM 账号 & AccessKey 密钥
1. 首先在右上角找到对应账号信息,然后点击 AccessKey 进入到对应页面之后会立即有一个弹窗,勾选对应确认再选择使用 RAM 用户 AccessKey
2. 接着找到身份管理下的用户,点击创建用户,接着根据自己的需求去配置用户账号信息,我在这里使用的是自定义密码且不充值,然后勾选相关的选项
注意:在创建完成之后记得先保存一下AccessKey ID和AccessKey Secret,这个在页面刷新之后就不会再有了,这两个 key 很重要,后续我们在代码开发中是需要用到的
3. 在创建好对应的用户之后,我给相关的用户添加了相关的权限,这里也可以根据你自己的需求来添加
04
—
NodeJs 如何写 OSS 图片上传
去阿里云官网找到 NodeJs 的文档,里面会用到 ali-oss 的包(在这里我还用到了 multer 的包,multer 是一个 NodeJs 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件,不会处理非 multipart/form-data 类型的表单数据),接着就是初始化的一些操作,里面就会有相关的一些配置
安装OSS Node.js SDK
在配制好上面的 OSS 信息之后,对应的实例化就创建好了,接着不卖关子了,在这里我就不重点讲代码了,在这里我把对应的代码贴到文档里面,有需求的同学可以直接复制出来去修改就可以用了(如果后续觉得代码有帮助的话,不妨帮我点点推荐或者关注一个再走呀)
import OSS from "ali-oss";
import multer from "multer";
import path from "path";
// 配置阿里云OSS客户端,具体信息按照上面图片中的配图来配置
const client = new OSS({
accessKeyId: "xxxxxx",
accessKeySecret: "xxxxx",
region: "xxxx",
authorizationV4: true,
bucket: "xxxxxx",
endpoint: "xxxxxx",
});
// 配置multer用于处理文件上传
const storage = multer.memoryStorage();
const upload = multer({
storage,
limits: {
fileSize: 10 * 1024 * 1024, // 限制文件大小为10MB
},
fileFilter: (req, file, cb) => {
// 只允许上传图片文件
const allowedTypes = [
"image/jpeg",
"image/png",
"image/webp",
];
if (allowedTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error("只支持上传图片格式文件"), false);
}
},
});
// 生成唯一文件名
const generateFileName = (originalName) => {
const timestamp = Date.now();
const random = Math.random().toString(36).substring(2);
const ext = path.extname(originalName);
// 这里会在阿里云oss上生成一个默认的文件夹,叫menu-images
return `menu-images/${timestamp}-${random}${ext}`;
};
// 上传图片到阿里云OSS的路由处理函数
const uploadImage = async (req, res) => {
try {
// 使用multer中间件处理文件上传
upload.single("uploadMenuPic")(req, res, async (err) => {
if (err) {
console.error("文件上传错误:", err);
return res.status(400).json({
code: 400,
message: err?.message || "文件上传失败",
});
}
try {
// 生成唯一文件名
const fileName = generateFileName(req.file.originalname);
// 上传文件到阿里云OSS
const result = await client.put(fileName, req.file.buffer);
// 返回上传成功的结果
res.json({
code: 0,
message: "图片上传成功",
data: {
// 这里使用的是自定义域名,如果用默认域名由于2019年起默认会在对应访问地址的header头部添加强制下载的属性,这个不符合我们预览的规范,只能使用自定义域名访问解决
url: `https://xxxx.com/${result.name}`,
},
});
} catch (ossError) {
console.error("OSS上传错误:", ossError);
res.status(500).json({
code: 500,
message: ossError?.message || "图片上传到云存储失败",
});
}
});
} catch (error) {
console.error("上传处理错误:", error);
res.status(500).json({
code: 500,
message: error?.message || "服务器内部错误",
});
}
};
export default uploadImage;
你是不是看到上面专门有一个自定义域名的解释,这里就是图片预览的一个坑,正常用户在访问图片连接的时候,想要的效果是预览而不是下载,如果直接用阿里云OSS自带的地址,由于在2019年起默认会在对应访问地址的header头部添加强制下载的属性,这个不符合我们预览的规范,只能使用自定义域名访问解决
05
—
如何配置自定义域名
在上面段落我们提到了自定义域名的概念,这个该如何配置呢?
首先找了一下官网的配置文档,大家可以参考这个文档:
绑定自定义域名至Bucket默认域名
https://help.aliyun.com/zh/oss/map-custom-domain-names-5?spm=a2c4g.11186623.0.i5
但是有些需要注意地方,我在这里提一下,官网这边要求添加CNAME,在添加CNAME之前需要去Bucket详情里面的权限控制下的阻止公共访问中,将对应的开关给关闭,接着再去读写权限里面将私有改为公共读(这个就是上面段落中在创建Bucket的时候那个按钮无法点击更改的问题)
接着就按照官网的提示去 Bucket 配置的域名管理,对应的域名千万不要选择你现在项目中已配置的域名,否则会提示“OSS的域名管理中绑定域名时提示“域名绑定在自己的其他Bucket上””。
这里你可以用自己的三级域名或者配置其它的域名。如果对应的主域名中有对应的 CNAME 类型,可以去公网权威解析中找到对应的域名,点击对应域名进入到域名详情里面,将对应 CNAME 删除重新添加记录,这里主机记录就按照官网的来改为 static,然后就点击创建。后续就可以继续按照官方文档去配置即可,后续图片访问的时候就用这个配置的自定义域名来访问,比如https://static.xxx.com/url_xxx,就不会再出现图片直接下载的问题了!
文章转载:阿里云OSS存储图片之nodejs

发表评论