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

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

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

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

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

相关推荐

搭建一个20人的办公网络(适用于20多人的小型办公网络环境)

楼主有5台机上网,则需要一个8口路由器,组网方法如下:设备:1、8口路由器一台,其中8口为LAN(局域网)端口,一个WAN(广域网)端口,价格100--400元2、网线N米,这个你自己会看了:)...

笔记本电脑各种参数介绍(笔记本电脑各项参数新手普及知识)

1、CPU:这个主要取决于频率和二级缓存,频率越高、二级缓存越大,速度越快,现在的CPU有三级缓存、四级缓存等,都影响相应速度。2、内存:内存的存取速度取决于接口、颗粒数量多少与储存大小,一般来说,内...

汉字上面带拼音输入法下载(字上面带拼音的输入法是哪个)

使用手机上的拼音输入法打成汉字的方法如下:1.打开手机上的拼音输入法,在输入框中输入汉字的拼音,例如“nihao”。2.根据输入法提示的候选词,选择正确的汉字。例如,如果输入“nihao”,输...

xpsp3安装版系统下载(windowsxpsp3安装教程)

xpsp3纯净版在采用微软封装部署技术的基础上,结合作者的实际工作经验,融合了许多实用的功能。它通过一键分区、一键装系统、自动装驱动、一键设定分辨率,一键填IP,一键Ghost备份(恢复)等一系列...

没有备份的手机数据怎么恢复

手机没有备份恢复数据方法如下1、使用数据线将手机与电脑连接好,在“我的电脑”中可以看到手机的盘符。  2、将手机开启USB调试模式。在手机设置中找到开发者选项,然后点击“开启USB调试模式”。  3、...

电脑怎么激活windows11专业版

win11专业版激活方法有多种,以下提供两种常用的激活方式:方法一:使用激活密钥激活。在win11桌面上右键点击“此电脑”,选择“属性”选项。进入属性页面后,点击“更改产品密钥或升级windows”。...

华为手机助手下载官网(华为手机助手app下载专区)

华为手机助手策略调整,已不支持从应用市场下载手机助手,目前华为手机助手是需要在电脑上下载或更新手机助手到最新版本,https://consumer.huawei.com/cn/support/his...

光纤线断了怎么接(宽带光纤线断了怎么接)

宽带光纤线断了可以重接,具体操作方法如下:1、光纤连接的时候要根据束管内,同色相连,同芯相连,按顺序进行连接,由大到小。一般有三种连接方法,分别是熔接、活动连接和机械连接。2、连接的时候要开剥光缆,抛...

深度操作系统安装教程(深度操作系统安装教程图解)
  • 深度操作系统安装教程(深度操作系统安装教程图解)
  • 深度操作系统安装教程(深度操作系统安装教程图解)
  • 深度操作系统安装教程(深度操作系统安装教程图解)
  • 深度操作系统安装教程(深度操作系统安装教程图解)
win7旗舰版和专业版区别(win7旗舰版跟专业版)

1、功能区别:Win7旗舰版比专业版多了三个功能,分别是Bitlocker、BitlockerToGo和多语言界面; 2、用途区别:旗舰版的功能是所有版本中最全最强大的,占用的系统资源,...

万能连接钥匙(万能wifi连接钥匙下载)

1、首先打开wifi万能钥匙软件,若手机没有开启WLAN,就根据软件提示打开WLAN开关;2、打开WLAN开关后,会显示附近的WiFi,如果知道密码,可点击相应WiFi后点击‘输入密码’连接;3、若不...

雨林木风音乐叫什么(雨林木风是啥)

雨林木风的创始人是陈年鑫先生。陈年鑫先生于1999年创立了雨林木风公司,其初衷是为满足中国市场对高品质、高性能电脑的需求。在陈年鑫先生的领导下,雨林木风以技术创新、产品质量和客户服务为核心价值,不断推...

aics6序列号永久序列号(aics6破解序列号)

关于AICS6这个版本,虽然是比较久远的版本,但是在功能上也是十分全面和强大的,作为一名平面设计师的话,AICS6的现有的功能已经能够应付几乎所有的设计工作了……到底AICC2019的功能是不是...

win7正在启动windows 卡住(win7正在启动windows卡住了 进入安全模式)
  • win7正在启动windows 卡住(win7正在启动windows卡住了 进入安全模式)
  • win7正在启动windows 卡住(win7正在启动windows卡住了 进入安全模式)
  • win7正在启动windows 卡住(win7正在启动windows卡住了 进入安全模式)
  • win7正在启动windows 卡住(win7正在启动windows卡住了 进入安全模式)
手机可以装电脑系统吗(手机可以装电脑系统吗怎么装)

答题公式1:手机可以通过数据线或无线连接的方式给电脑装系统。手机安装系统需要一定的技巧和软件支持,一般需要通过数据线或无线连接的方式与电脑连接,并下载相应的软件和系统文件进行安装。对于大部分手机用户来...