不少项目会把图片、视频和日志放到阿里云OSS上。容量可以按需扩展,计费按量,用起来省心。真正动手写阿里云oss上传的代码时,问题通常出在三个地方:Bucket权限没配对,大文件传到一半超时,浏览器直传时报跨域错误。这篇文章用一个电商商品图上传的例子,把常见的上传方式和配置细节过一遍。

一、上传前的准备
下面三步做完,后面的代码才能顺利跑通。
- 创建Bucket:在OSS控制台新建Bucket,地域选离用户最近的,比如华东1(杭州)。读写权限保持私有,访问靠签名或授权来控制,不要图省事开成公共读。
- 创建RAM子账号:在RAM控制台新建专用子账号,只授予目标Bucket的读写权限。代码里直接用主账号的AccessKey,等于把整个账号交出去,一旦泄露,影响范围很难收住。
- 记下Endpoint:格式通常是 https://oss-cn-hangzhou.aliyuncs.com。后面的所有配置都要和Bucket所在的地域对得上。
二、五种常见的上传方式
1. 控制台手动上传
适合临时传几个文件,比如补一批素材或者排查问题。进入Bucket的文件管理页面点击上传即可。文件较大时,控制台会自动切换为分片上传,不需要额外设置。
2. 使用Python SDK简单上传
后端服务最常见的写法。下面的例子使用官方的oss2库,AccessKey从环境变量读取,代码里不留明文:
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',
'your-bucket-name')
# 上传本地文件,第一个参数为OSS中的对象路径
result = bucket.put_object_from_file('products/1001/main.jpg',
'local/main.jpg')
print(result.status) # 返回200表示成功
第一个参数是OSS中的对象路径,第二个是本地文件路径。像 products/1001/ 这样的前缀并不会真的创建目录,它只是对象名的一部分,控制台会按前缀把它显示成文件夹。返回状态码200即表示成功。
3. 大文件分片断点续传
单次PUT请求的上限是5GB,超过这个大小就该用分片。oss2提供的resumable_upload会自动切片,网络中断后从已完成的分片继续,视频和备份包这类大文件用它最省心。分片大小一般在1MB到10MB之间。太小,请求次数多,整体反而慢;太大,一片失败就得整片重传。另外,分片数上限是10000个,分片大小要和文件大小一起算,别让大文件撞到这个上限。
4. 前端直传(预签名URL)
让浏览器直接把文件传到OSS,应用服务器只负责签发一个有时效的预签名URL,不再经手文件内容。前端拿到URL后用PUT方法上传即可。示例中的商品图上传就是这样改的,服务器带宽占用下降了七成以上。
5. 使用STS临时凭证
上传端是移动App或第三方客户端时,不要下发长期有效的AccessKey。一旦客户端被反编译或者凭证泄露,风险很大。改用STS获取有效期约一小时的临时凭证,再把权限限制在具体的路径前缀上,泄露后的影响会小很多。
三、一个真实案例的复盘
某中型电商团队最初用的是方式二,商品图全部经由应用服务器中转。大促期间,服务器出口带宽被打满,上传接口的平均响应时间从300毫秒涨到4秒,用户看到的就是一直转圈。
后来他们把商品图改成预签名直传,上传请求不再经过业务服务器,接口响应恢复正常。视频素材则换成了分片断点续传,弱网环境下的失败率从15%降到了不足2%。直传之前,权限和跨域规则要先配好,这一步省不得。
四、三个常见的坑
- 跨域报错:浏览器直传时,请求会先发一个OPTIONS预检。需要在Bucket的跨域设置里添加允许的来源、PUT方法和Content-Type请求头,否则预检不通过,真正的上传请求根本发不出去。本地调试时来源可以写成 http://localhost:端口,上线前再收紧为正式域名。
- Endpoint选错地域:Bucket在杭州,代码里却填了北京的Endpoint,返回的错误往往是403或404,信息含糊,很容易被带去排查签名和权限。遇到这类报错,先核对地域,这一步最省时间。
- 对象路径设计:所有文件堆在同一层目录,后期查找和清理都很麻烦。按业务和日期分层,比如 products/年月日/,之后配置生命周期规则时也能按前缀精准匹配。
五、怎么选上传方式
选方式的依据是文件大小、上传端和安全要求。小文件由后端直传就够用;大文件用分片续传;浏览器和移动端场景优先用预签名URL或STS临时凭证,别把长期AccessKey放到客户端。动手前把子账号权限、Endpoint和跨域规则核对一遍,大部分报错都能提前避开。