百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

深入掌握 OSS:最完美的 OSS 上传方案!

liuian 2025-04-06 18:08 95 浏览

文件上传是常见需求,一般我们不会把文件直接上传到应用服务器,因为单台服务器存储空间是有限的,不好扩展。

我们会用单独的 OSS (Object Storage Service)对象存储服务来上传下载文件。

比如一般会买阿里云的 OSS 服务。

我们本地文件存储是目录-文件的组织方式:

而 OSS 服务的存储结构是这样的:

一个桶里放一些文件。

阿里云 OSS 的控制台也提到了对象存储没有目录层级结构:

但下面明明是支持目录的呀:

这其实只是模拟实现的。

Object 会存储 id、文件内容、元数据三部分信息:

阿里云 OSS 只是用元信息部分模拟实现了目录。

就像打了个 tag 一样,并不是说文件存储在这个 tag 下,只是你可以用这个 tag 来检索文件。

除了对象存储 OSS,阿里云也提供了文件存储和块存储的方式:

块存储就是把整块磁盘给你用,你需要自己格式化,存储容量有限。

文件存储就是有目录层次结构,你可以上传下载文件,存储容量有限。

对象存储就是 key-value 存储,分布式的方式实现的,存储容量无限。

这些简单了解就行,绝大多数情况下,我们都是用 OSS 对象存储。

我们买个阿里云的 OSS 服务来试试看:

我买了 40G 的 OSS 国内通用资源包,花了 5 块钱。

然后我们创建个 Bucket(桶):

在北京创建了一个 Bucket,文件就会存储在那里的服务器上。

设置公共读,也就是这些文件大家都可以直接访问。

不然私有的方式,你访问每个文件都要带上一些身份信息:

有的同学说,不是静态文件要在全国各地都能访问到么?存在北京的服务器会不会访问速度慢?

这是 CDN 的活:

接入 CDN 后,访问该域名会走到云服务的 DNS,然后返回一台最近的缓存服务器的地址,这台服务器会从源站拿文件来缓存,之后就不再访问源站。

这里的源站就可以是 OSS 服务。

创建 Bucket 之后,我们上传个文件试试:

上传完之后在文件列表就可以看到这个文件了:

点开可以看到文件详情,用这个 URL 就可以访问:

当然,生产环境下我们不会直接用 OSS 的 URL 访问,而是会开启 CDN,用网站域名访问,最终回源到 OSS 服务:

在控制台里上传很简单,那如果想在代码里上传呢?

官方文档里有示例代码,我们试试看:

mkdir oss-test
cd oss-test
npm init -y

安装用到的包:

npm install ali-oss

写下代码:

const OSS = require('ali-oss')

const client = new OSS({
region: 'oss-cn-beijing',
bucket: 'guang-333',
accessKeyId: '',
accessKeySecret: '',
});

async function put () {
try {
const result = await client.put('cat.png', './mao.png');
console.log(result);
} catch (e) {
console.log(e);
}
}

put();

region 在概览里可以看到:

这里的 accessKeyId 和 acessKeySecret 是什么呢?

本来我们身份认证都是通过用户名密码:

但这样不够安全,所以我们创建了 accessKey 用来代表身份,用它来做身份认证,就算泄漏了,也不影响别的:

我们创建个 accesKey:

创建完成后,拿到 accesKeyId 和 accessKeySecret 后运行代码:

这里的 mao.png 是这样的:

在控制台可以看到上传成功了:

这就是 OSS 用 api 上传文件的用法。

只是我们刚刚用的 accessKey 不够安全。

打开 accessKey 管理页面的时候就提示了:

让我们不要直接用 accessKey,而是创建一个子用户再创建 accessKey。

那我们就创建个子用户:

然后用这个 accessKey 的 id 和 secret 就好了:

但你直接换上它还不行:

会提示你 403,没有权限。

需要你授权下:

新增一个授权:

把 OSS 的管理和读取权限给这个子用户:

然后再试下:

这时候就上传成功了。

回过头来看下,不得不说阿里云在安全这一块设计的就很巧妙。

如果我们直接用用户名密码验证呢:

那万一泄漏了不就完蛋了么?

但是如果创建个 accessKey 用它来做身份认证:

就算泄漏了我也可以禁用啊:

再进一步,直接用这个 accessKey 它是有所有权限的。

我们先创建个 RAM 子用户,再分配给他某些权限,这样就算泄漏了,是不是能做的事情就更少了?

当然就更安全。

所以说,阿里云这套 accessKey 和 RAM 子用户的身份认证方式,还是很不错的。

再说回 OSS,一般的文件直接上传就行,涉及到大文件就要分片上传了。

分片上传实现原理是前端常见面试题了,大家都能答上来。

就是把文件用 slice 方法分成一个个小的片,然后全部上传完之后请求一个接口合并分片。

阿里云的大文件分片上传也是这样实现的:

具体怎么用直接看文档就好了,这里我们就不试了:

有了 OSS 服务之后,我们上传文件还需要经过应用服务器么?

可以经过也可以不经过。

如果经过应用服务器,那就要客户端上传文件之后,我们在服务里接受文件,上传 OSS:

这样当然是可以的,还能保护 accessKey 不被人窃取。

只是会浪费应用服务器的流量。

那如果不经过呢?

在客户端用 accessKey 把文件传到 OSS,之后把 URL 传给应用服务器就好了。

这样减少了应用服务器的流量消耗,但是增加了 accessKey 暴露的风险。

各有各的坏处。

那有没有啥两全其美的办法呢?

有。

阿里云的文档里也提到了这个问题。

它给出的解决方案就是生成一个临时的签名来用。

代码是这样的:

const OSS = require('ali-oss')

async function main() {
  
const config = {
region: 'oss-cn-beijing',
bucket: 'guang-333',
accessKeyId: '',
accessKeySecret: '',
}

const client = new OSS(config);

const date = new Date();

date.setDate(date.getDate() + 1);

const res = client.calculatePostSignature({
expiration: date.toISOString(),
conditions: [
["content-length-range", 0, 1048576000], //设置上传文件的大小限制。
]
});

console.log(res);

const location = await client.getBucketLocation();

const host = `http://${config.bucket}.${location.location}.aliyuncs.com`;
  
console.log(host);
}

main();

上传 OSS 的地址,用的临时 signature 和 policy 都有了:

这些代码不用记,文档里都有:

这样就能在网页里用这些来上传文件到 OSS 了:

创建个 index.html






Document
<script src="https://unpkg.com/axios@1.6.5/dist/axios.min.js"></script>




<script>
const fileInput = document.getElementById('fileInput');

async function getOSSInfo() {
await '请求应用服务器拿到临时凭证';
return {
OSSAccessKeyId: 'LTAI5tDemEBPwQkTx65jZCdy',
Signature: 'NfXgq/qLIR2/v87j/XC9sjrASOA=',
policy: 'eyJleHBpcmF0aW9uIjoiMjAyNC0wMS0yMFQwMzoyNjowOC4xMDZaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF1dfQ==',
host: 'http://guang-333.oss-cn-beijing.aliyuncs.com'
}
}

fileInput.onchange = async () => {
const file = fileInput.files[0];
  
const ossInfo = await getOSSInfo();
  
  
const formdata = new FormData()

formdata.append('key', file.name);
formdata.append('OSSAccessKeyId', ossInfo.OSSAccessKeyId)
formdata.append('policy', ossInfo.policy)
formdata.append('signature', ossInfo.Signature)
formdata.append('success_action_status', '200')
formdata.append('file', file)
  
const res = await axios.post(ossInfo.host, formdata);
if(res.status === 200) {

const img = document.createElement('img');
img.src = ossInfo.host + '/' + file.name
document.body.append(img);
  
alert('上传成功');
}
}
</script>

这里 getOSSInfo 应该是请求服务端的接口,拿到刚才我们控制台输出的那些东西。

这里就简化下,直接写死在代码里了。

引入 axios,用这些信息来上传文件。

跑个静态服务器:

npx http-server .

这时候你上传文件的时候会提示跨域错误:

我们在控制台开启下跨域:

然后再试下:

上传成功了!

控制台文件列表也可以看到这个文件:

这就是完美的 OSS 上传方案。

服务端用 RAM 子用户的 accessKey 来生成临时签名,然后返回给客户端,客户端用这个来直传文件到 OSS。

因为临时的签名过期时间很短,我们设置的是一天,所以暴露的风险也不大。

这样服务端就根本没有接受文件的压力,只要等客户端上传完之后,带上 URL 就好了。

案例代码上传了 github:github.com/QuarkGluonP…

总结

上传文件一般不会直接存在服务器目录下,这样不好扩展,一般我们会用阿里云的 OSS,它会自己做弹性扩展,所以存储空间是无限的。

OSS 对象存储是在一个 bucket 桶下,存放多个文件。

它是用 key-value 存储的,没有目录的概念,阿里云 OSS 的目录只是用元信息来模拟实现的。

我们在测试了在控制台的文件上传,也测试过了 node 里用 ali-oss 包来上传、在网页里直传 OSS 这三种上传方式。

不管在哪里上传,都需要 acessKeyId 和 acessKeySecret。

这个是阿里云的安全策略,因为直接用用户名密码,一旦泄漏就很麻烦,而 acessKey 泄漏了也可以禁用。而且建议用 RAM 子用户的方式生成 accessKey,这样可以最小化权限,进一步减少泄漏的风险。

客户端直传 OSS 的方式不需要消耗服务器的资源,但是会有泄漏 acessKey 的风险,所以一般都是用服务端生成临时的签名等信息,然后用这些信息来上传。

这种方案就是最完美的 OSS 上传方案了。

掌握了这些,就完全足够应对工作中的 OSS 使用了。


作者:zxg_神说要有光
链接:
https://juejin.cn/post/7325495635455868938

相关推荐

驱动网卡(怎么从新驱动网卡)
驱动网卡(怎么从新驱动网卡)

网卡一般是指为电脑主机提供有线无线网络功能的适配器。而网卡驱动指的就是电脑连接识别这些网卡型号的桥梁。网卡只有打上了网卡驱动才能正常使用。并不是说所有的网卡一插到电脑上面就能进行数据传输了,他都需要里面芯片组的驱动文件才能支持他进行数据传输...

2026-01-30 00:37 liuian

win10更新助手装系统(微软win10更新助手)

1、点击首页“系统升级”的按钮,给出弹框,告诉用户需要上传IMEI码才能使用升级服务。同时给出同意和取消按钮。华为手机助手2、点击同意,则进入到“系统升级”功能华为手机助手华为手机助手3、在检测界面,...

windows11专业版密钥最新(windows11专业版激活码永久)

 Windows11专业版的正版密钥,我们是对windows的激活所必备的工具。该密钥我们可以通过微软商城或者通过计算机的硬件供应商去购买获得。获得了windows11专业版的正版密钥后,我...

手机删过的软件恢复(手机删除过的软件怎么恢复)
手机删过的软件恢复(手机删除过的软件怎么恢复)

操作步骤:1、首先,我们需要先打开手机。然后在许多图标中找到带有[文件管理]文本的图标,然后单击“文件管理”进入页面。2、进入页面后,我们将在顶部看到一行文本:手机,最新信息,文档,视频,图片,音乐,收藏,最后是我们正在寻找的[更多],单击...

2026-01-29 23:55 liuian

一键ghost手动备份系统步骤(一键ghost 备份)

  步骤1、首先把装有一键GHOST装系统的U盘插在电脑上,然后打开电脑马上按F2或DEL键入BIOS界面,然后就选择BOOT打USDHDD模式选择好,然后按F10键保存,电脑就会马上重启。  步骤...

怎么创建局域网(怎么创建局域网打游戏)

  1、购买路由器一台。进入路由器把dhcp功能打开  2、购买一台交换机。从路由器lan端口拉出一条网线查到交换机的任意一个端口上。  3、两台以上电脑。从交换机任意端口拉出网线插到电脑上(电脑设置...

精灵驱动器官方下载(精灵驱动手机版下载)

是的。驱动精灵是一款集驱动管理和硬件检测于一体的、专业级的驱动管理和维护工具。驱动精灵为用户提供驱动备份、恢复、安装、删除、在线更新等实用功能。1、全新驱动精灵2012引擎,大幅提升硬件和驱动辨识能力...

一键还原系统步骤(一键还原系统有哪些)

1、首先需要下载安装一下Windows一键还原程序,在安装程序窗口中,点击“下一步”,弹出“用户许可协议”窗口,选择“我同意该许可协议的条款”,并点击“下一步”。  2、在弹出的“准备安装”窗口中,可...

电脑加速器哪个好(电脑加速器哪款好)

我认为pp加速器最好用,飞速土豆太懒,急速酷六根本不工作。pp加速器什么网页都加速,太任劳任怨了!以上是个人观点,具体性能请自己试。ps:我家电脑性能很好。迅游加速盒子是可以加速电脑的。因为有过之...

任何u盘都可以做启动盘吗(u盘必须做成启动盘才能装系统吗)

是的,需要注意,U盘的大小要在4G以上,最好是8G以上,因为启动盘里面需要装系统,内存小的话,不能用来安装系统。内存卡或者U盘或者移动硬盘都可以用来做启动盘安装系统。普通的U盘就可以,不过最好U盘...

u盘怎么恢复文件(u盘文件恢复的方法)

开360安全卫士,点击上面的“功能大全”。点击文件恢复然后点击“数据”下的“文件恢复”功能。选择驱动接着选择需要恢复的驱动,选择接入的U盘。点击开始扫描选好就点击中间的“开始扫描”,开始扫描U盘数据。...

系统虚拟内存太低怎么办(系统虚拟内存占用过高什么原因)

1.检查系统虚拟内存使用情况,如果发现有大量的空闲内存,可以尝试释放一些不必要的进程,以释放内存空间。2.如果系统虚拟内存使用率较高,可以尝试增加系统虚拟内存的大小,以便更多的应用程序可以使用更多...

剪贴板权限设置方法(剪贴板访问权限)
剪贴板权限设置方法(剪贴板访问权限)

1、首先打开iphone手机,触碰并按住单词或图像直到显示选择选项。2、其次,然后选取“拷贝”或“剪贴板”。3、勾选需要的“权限”,最后选择开启,即可完成苹果剪贴板权限设置。仅参考1.打开苹果手机设置按钮,点击【通用】。2.点击【键盘】,再...

2026-01-29 21:37 liuian

平板系统重装大师(平板重装win系统)

如果你的平板开不了机,但可以连接上电脑,那就能好办,楼主下载安装个平板刷机王到你的个人电脑上,然后连接你的平板,平板刷机王会自动识别你的平板,平板刷机王上有你平板的我刷机包,楼主点击下载一个,下载完成...

联想官网售后服务网点(联想官网售后服务热线)

联想3c服务中心是联想旗下的官方售后,是基于互联网O2O模式开发的全新服务平台。可以为终端用户提供多品牌手机、电脑以及其他3C类产品的维修、保养和保险服务。根据客户需求层次,联想服务针对个人及家庭客户...