动手之前先看三样东西:Bucket 在哪个地域,手里的访问凭证能做什么,文件有多大、谁需要访问。这三个问题的答案基本决定了该用哪种方法。

OSS 的访问地址(Endpoint)跟地域绑定,比如华东1(杭州)的地址是 oss-cn-hangzhou.aliyuncs.com。Endpoint 和 Bucket 不在同一地域时,请求通常会报错或者很慢,所以别凭印象写,先去控制台确认 Bucket 的地域。
凭证建议用 RAM 子账号的 AccessKey,权限只授予目标 Bucket 的 oss:PutObject。日常上传不要用主账号密钥。主账号密钥一旦泄露,整个账号都会受影响,子账号泄露的影响范围小得多。
二、控制台上传:偶尔传几个文件时最省事
一张产品图、一份说明文档,直接用控制台就够了。
- 登录 OSS 控制台,进入目标 Bucket 的“文件管理”页面。
- 点“上传文件”,选择本地文件。不指定路径的话,文件会落在 Bucket 根目录下。
- 需要分类存放时,在“目标路径”里填写,比如 images/2024/。末尾的斜杠表示这是一个目录。
- 上传完成后打开文件详情,复制外链地址实际访问一次,确认权限和预期一致。
控制台对单个文件的大小有限制。文件一大,就换到下面的命令行或 SDK。
三、ossutil 命令行:适合运维脚本和定时任务
ossutil 是阿里云官方的命令行工具,写进脚本或 crontab 很顺手。第一次使用先运行 ossutil config,按提示填入 Endpoint、AccessKeyId 和 AccessKeySecret。配置会保存在用户目录下的本地文件里,记得把该文件的权限收紧到仅当前用户可读。
上传单个文件:
ossutil cp ./report.pdf oss://my-bucket/docs/report.pdf
上传整个目录,子目录一并处理:
ossutil cp ./photos oss://my-bucket/photos -r
如果是每天都要同步的一批文件,加上 –update 参数更划算。它只传有变化的文件,已经同步过的会跳过。文件量大时,这一点能省下不少时间和流量。
四、Python SDK:上传逻辑要嵌进业务代码时
当上传动作和业务流程绑在一起,比如用户提交表单后自动保存图片,SDK 更合适。下面以官方的 oss2 库为例,先执行 pip install oss2 安装。
密钥不要写死在代码里,统一从环境变量读取:
import os
import oss2
auth = oss2.Auth(os.environ['OSS_ACCESS_KEY_ID'], os.environ['OSS_ACCESS_KEY_SECRET'])
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'my-bucket')
result = bucket.put_object_from_file('images/logo.png', 'local/logo.png')
print(result.status) # 200 表示成功
这段代码把本地的 local/logo.png 上传到 Bucket 的 images/ 目录下,返回结果的 status 为 200 即成功。生产环境里,调用最好包在 try 块中,捕获 oss2.exceptions.OssError,同时记录 request_id。之后向阿里云提交工单排查时,这个 ID 能省去很多来回沟通。
五、大文件用分片上传
大文件如果用一次 PUT 发出去,中途断开就得从头再来。分片上传把文件切成若干块并行传输,哪一块失败,只重传那一块。
oss2 的 resumable_upload 把这些都封装好了,自动分片、并发上传,中断后还能续传:
import oss2
oss2.resumable_upload(bucket, 'videos/course01.mp4', 'local/course01.mp4',
multipart_threshold=100*1024*1024,
part_size=10*1024*1024,
num_threads=4)
三个参数分别控制:multipart_threshold 是启用分片的文件大小阈值,这里是 100MB;part_size 是每个分片的大小,这里是 10MB;num_threads 是并发线程数。带宽充足时可以调高,但线程太多会占满本机带宽和连接数,最好用自己的文件实测一下。
如果上传的是几 GB 的视频,网络不稳定时,分片加并发通常能明显提高完成率。提升多少取决于你的网络环境,不必照搬别人的数字。
六、前端直传:别让服务器中转文件
用户上传头像或附件时,如果文件先经过自己的服务器再转存到 OSS,带宽和内存都会被占用。更常见的做法是由服务端生成预签名 URL,客户端拿到后直接上传到 OSS。
服务端生成一个 10 分钟有效的上传地址:
url = bucket.sign_url('PUT', 'avatars/u123.jpg', 600)
客户端用 HTTP PUT 把文件内容发到这个地址即可。URL 只对指定的对象键有效,过期自动失效,泄露后的风险可控。如果同一个用户需要上传到多个路径,可以改用 STS 临时凭证,再通过 RAM 策略限定路径前缀。
七、常见问题
- 上传后打不开:多数时候是 Bucket 设为私有读。需要生成带签名的下载地址,或者在确认安全的前提下调整读权限。
- 中文文件名显示乱码:对象键统一使用 UTF-8,客户端和服务端的编码要保持一致。
- 同名文件被覆盖:OSS 不会弹出覆盖提醒。业务需要保留历史版本的话,在 Bucket 上开启版本控制。
- 账单突然变高:定期检查生命周期规则,把长期不访问的文件转为低频或归档存储。未完成的分片也会计费,记得清理。
安全上记住三点:密钥只放在环境变量或密钥管理服务里;Bucket 默认保持私有;上传权限按路径和操作类型拆开授权。这三点做好,很多安全问题都能提前挡住。