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

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

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

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

我们会用单独的 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

相关推荐

电脑怎么强制恢复出厂设置win10
  • 电脑怎么强制恢复出厂设置win10
  • 电脑怎么强制恢复出厂设置win10
  • 电脑怎么强制恢复出厂设置win10
  • 电脑怎么强制恢复出厂设置win10
磊科无线路由器手机设置(用手机 怎么设置磊科路由器怎么设置密码)

  刚要回答你磊科无线路由器怎么设置无线网络这个大问题,看后面估计你更想知道的不是磊科无线路由器怎么设置无线网络,而是怎么用手机设置网络吧,其实很简单的,我刚才还用手机设置我刚买的极贰的网络  手机只...

萝卜家园xp系统安装(萝卜家园xp系统安装步骤及图片)

先用大白菜制作u盘启动项。再下载萝卜家园系统,放到u盘。开机选择用u盘启动,进入pe,打开ghost加载系统执行安装。

台式电脑显卡安装步骤图(台式机显卡怎么安装图解)

关于这个问题,1.确认电脑是否支持显卡首先,要确认电脑是否支持显卡。如果是台式机,需要确认主板是否支持PCI-E插槽;如果是笔记本电脑,则需要确认是否有可更换显卡的插槽。2.卸下原有显卡如果你的电...

win11免费下载(win11正式版下载)
  • win11免费下载(win11正式版下载)
  • win11免费下载(win11正式版下载)
  • win11免费下载(win11正式版下载)
  • win11免费下载(win11正式版下载)
虚拟光驱推荐(虚拟光驱推荐知乎)

虚拟光驱是一种计算机软件,用于模拟物理光驱的功能。它可以将光盘的内容转化为电脑上的虚拟光盘,用户可以在计算机上直接使用虚拟光盘中的文件和程序,而无需实际插入光盘。虚拟光驱的主要功能包括:1.安装软件...

win7和win10互联(win7和win10可以网络共享吗)

一台电脑只要已经使用过一次已经激活的win10,以后可以随便重装win10,都会自动激活。不限制次数,只要你不把这台电脑的主板给换掉即可。所以可以随时重装,或者也可以使用win7、win8.1的密钥...

电脑给另一个硬盘装系统(电脑给另一块硬盘装系统)

回答如下:以下是在Windows操作系统下的步骤:1.确保你有一个可用的Windows安装光盘或USB安装介质。2.将另一个硬盘连接到计算机上并确保电脑识别到它。3.打开计算机BIOS并确保在启...

设计师专用笔记本电脑排行榜

惠普战99采用了英特尔第十二代酷睿i7-12700H标压处理器和英伟达T600工作站级专业显卡的配置。存储方面支持双通道3200MHz内存和双M.2接口SSD,配置十分豪华。15.6英寸高色域高清IP...

打印机故障排查(打印机故障排查提示不接收任务怎么处理)
打印机故障排查(打印机故障排查提示不接收任务怎么处理)

步骤/方式1点击电脑桌面左下角的开始按钮,选择设备和打印机的选项。步骤/方式2找到有故障的打印机,鼠标右键点击选择属性的选项。步骤/方式3在打印机属性页面,我们点击维护的选项。步骤/方式4在维护页面,选择对应的故障进行维护,即可解决故障亮灯...

2026-01-09 19:55 liuian

内部版本7601激活(内部版本7601影响使用吗)

激活方法如下右击计算机--属性,拉倒最下面,会提示该系统未激活,然后点击激活,输入密钥就可以了,需要连接互联网。如果没有互联网,也可以电话激活。下载安装内部专用激活工具激活就可以了Windows7内部...

microsoft打不开怎么办(microsoftoffice打不开)

方法一:1、按Win+S组合键,或点击底部任务栏开始旁的搜索图标,在打开的Windows搜索窗口,搜索框输入服务,然后点击打开系统给出的最佳匹配服务应用;2、服务窗口,找到并双击打开WLA...

安卓仿苹果ios主题下载免费(安卓仿苹果ios12主题下载)

要把华为手机的主题改成类似iOS的风格,可以按照以下步骤进行操作:1.在华为应用商店中搜索并下载一个适合的iOS主题,例如iOSLauncher等。2.安装完成后,打开该主题应用,在设置中选择启...

声卡驱动安装哪个比较好(声卡驱动应该安装在哪里)

EXPSoundboard软件使用电脑自带的集成声卡就可以了。只是需要安装一些变声软件。如EXPSoundboard软件,使用这款EXPSoundboard中文版可以让你自由自在的在任何游戏中挂...

宽带登录网站(宽带登录网站怎么登录)

在浏览器内输入www.10010.com,进入中国联通网上营业厅后,选择“登录”,输入宽带账号与宽带密码,点击登录即可使用联通宽带登录联通网上营业厅。可通过以下方式办理联通宽带预约服务:1、登录联通网...