传统 OSS 上传方案,需要先从客户端上传到 Web 服务器,再从 Web 服务器上传到 OSS 服务器,文件经过中转导致消耗了流量和时间,另外如果客户端并发上传,对 Web 服务器带宽和性能都是不小的压力。
但是如果直接使用前端签名上传的话,则会有安全问题。
因此就有了服务端签名后直传方案。
官方文档:https://help.aliyun.com/document_detail/31926.html。
如果需要获取上传回调,进行特殊操作,可以查看 服务端签名直传并设置上传回调。
服务端签名前端直传方案流程如下:

服务端签名
这里使用 nodejs 作为示例。有官方的 SDK,省的我们对接阿里云 HTTP 接口造轮子。
安装 SDK
我使用的 sdk 是 ali-oss:https://github.com/ali-sdk/ali-oss。
吐槽下,阿里 sdk 命名不统一,
@alicloud/xxx,ali_sdk/xxx…
执行 npm install 安装 sdk。
1 | npm install ali-oss --save |
构建 Post Policy,获取上传签名
这里可以参照下官方 SDK 的 demo:https://github.com/ali-sdk/ali-oss/blob/master/example/server/postObject.js
1 | const config = { |
Post Policy 的详细介绍:https://help.aliyun.com/document_detail/31988.html
必须包含 expiration 和 conditions。
Expiration: 指定过期时间
Conditions: 是一个列表,用来指定 Post 请求的表单域合法值。
Conditions 使用方式见下图:

前端使用签名直传
这里以支付宝小程序为例,其他平台类似。
1 | // 假设服务端获取上传签名接口返回值存储到 apiRet 变量 |
需要注意的点
有一个安全问题需要注意,如果黑客获取签名后,可以直接伪造请求,覆盖之前用户上传的图片,如果用户之前上传的是自己的付款码,可以直接修改为黑客的付款码。
解决方案如下:
生成签名时,conditions 指定 key 前缀(可以使用基于时间戳的 uuid),前端上传时,使用该前缀 key + 前端随机串上传。