Post Object
Post Object使用HTML表单上传文件到指定bucket。Post作为Put的替代品,使得基于浏览器上传文件到bucket成为可能。Post Object的消息实体通过多重表单格式(multipart/form-data)编码,在Put Object操作中参数通过HTTP请求头传递,在Post操作中参数则作为消息实体中的表单域传递。
Post object
请求语法POST / HTTP/1.1
Host: BucketName.oss-cn-hangzhou.aliyuncs.com
User-Agent: browser_data
Content-Length:ContentLength
Content-Type: multipart/form-data; boundary=9431149156168
--9431149156168
Content-Disposition: form-data; name="key"
key
--9431149156168
Content-Disposition: form-data; name="success_action_redirect"
success_redirect
--9431149156168
Content-Disposition: form-data; name="Content-Disposition"
attachment;filename=oss_download.jpg
--9431149156168
Content-Disposition: form-data; name="x-oss-meta-uuid"
myuuid
--9431149156168
Content-Disposition: form-data; name="x-oss-meta-tag"
mytag
--9431149156168
Content-Disposition: form-data; name="OSSAccessKeyId"
access-key-id
--9431149156168
Content-Disposition: form-data; name="policy"
encoded_policy
--9431149156168
Content-Disposition: form-data; name="Signature"
signature
--9431149156168
Content-Disposition: form-data; name="file"; filename="MyFilename.jpg"
Content-Type: image/jpeg
file_content
--9431149156168
Content-Disposition: form-data; name="submit"
Upload to OSS
--9431149156168--
表单域
响应Header
响应元素(Response Elements)
细节分析
- 进行Post操作要求对bucket有写权限,如果bucket为public-read-write,可以不上传签名信息,否则要求对该操作进行签名验证。与Put操作不同,Post操作使用AccessKeySecret对policy进行签名计算出签名字符串作为Signature表单域的值,OSS会验证该值从而判断签名的合法性。
- 无论bucket是否为public-read-write,一旦上传OSSAccessKeyId, policy, Signature表单域中的任意一个,则另两个表单域为必选项,缺失时OSS会返回错误码:InvalidArgument。
- post操作提交表单编码必须为“multipart/form-data”,即header中Content-Type为multipart/form-data; boundary=xxxxxx这样的形式,boundary为边界字符串。
- 提交表单的URL为bucket域名即可,不需要在URL中指定object。即请求行是POST / HTTP/1.1,不能写成POST /ObjectName HTTP/1.1
- policy规定了该次Post请求中表单域的合法值,OSS会根据policy判断请求的合法性,如果不合法会返回错误码:AccessDenied。在检查policy合法性时,policy中不涉及的表单域不进行检查。
- 表单和policy必须使用UTF-8编码,policy为经过UTF-8编码和base64编码的JSON。
- Post请求中可以包含额外的表单域,OSS会根据policy对这些表单域检查合法性。
- 如果用户上传了Content-MD5请求头,OSS会计算body的Content-MD5并检查一致性,如果不一致,将返回InvalidDigest错误码。
- 如果POST请求中包含Header签名信息或URL签名信息,OSS不会对它们做检查。
- 如果请求中携带以x-oss-meta-为前缀的表单域,则视为user meta,比如x-oss-meta-location。一个Object可以有多个类似的参数,但所有的user meta总大小不能超过8k。
- Post请求的body总长度不允许超过5G。若文件长度过大,会返回错误码:EntityTooLarge。
- 如果上传指定了x-oss-server-side-encryption Header请求域,则必须设置其值为AES256,否则会返回400和错误码:InvalidEncryptionAlgorithmError。指定该Header后,在响应头中也会返回该Header,OSS会对上传的Object进行加密编码存储,当这个Object被下载时,响应头中会包含x-oss-server-side-encryption,值被设置成该Object的加密算法。
- 表单域为大小写不敏感的,但是表单域的值为大小写敏感的。
示例
[backcolor=transparent]请求示例:
POST / HTTP/1.1
Host: oss-example.oss-cn-hangzhou.aliyuncs.com
Content-Length: 344606
Content-Type: multipart/form-data; boundary=9431149156168
--9431149156168
Content-Disposition: form-data; name="key"
/user/a/${filename}
--9431149156168
Content-Disposition: form-data; name="success_action_status"
200
--9431149156168
Content-Disposition: form-data; name="Content-Disposition"
content_disposition
--9431149156168
Content-Disposition: form-data; name="x-oss-meta-uuid"
uuid
--9431149156168
Content-Disposition: form-data; name="x-oss-meta-tag"
metadata
--9431149156168
Content-Disposition: form-data; name="OSSAccessKeyId"
44CF9590006BF252F707
--9431149156168
Content-Disposition: form-data; name="policy"
eyJleHBpcmF0aW9uIjoiMjAxMy0xMi0wMVQxMjowMDowMFoiLCJj b25kaXRpb25zIjpbWyJj b250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIDEwNDg1NzYwXSx7ImJ1Y2tldCI6ImFoYWhhIn0sIHsiQSI6ICJhIn0seyJrZXkiOiAiQUJDIn1dfQ==
--9431149156168
Content-Disposition: form-data; name="Signature"
kZoYNv66bsmc10+dcGKw5x2PRrk=
--9431149156168
Content-Disposition: form-data; name="file"; filename="MyFilename.txt"
Content-Type: text/plain
abcdefg
--9431149156168
Content-Disposition: form-data; name="submit"
Upload to OSS
--9431149156168--
[backcolor=transparent]返回示例:
HTTP/1.1 200 OK
x-oss-request-id: 61d2042d-1b68-6708-5906-33d81921362e
Date: Fri, 24 Feb 2014 06:03:28 GMT
ETag: 5B3C1A2E053D763E1B002CC607C5A0FE
Connection: keep-alive
Content-Length: 0
Server: AliyunOSS
Post Policy
Post请求的policy表单域用于验证请求的合法性。 policy为一段经过UTF-8和base64编码的JSON文本,声明了Post请求必须满足的条件。虽然对于public-read-write的bucket上传时,post表单域为可选项,我们强烈建议使用该域来限制Post请求。
policy示例{ "expiration": "2014-12-01T12:00:00.000Z",
"conditions": [
{"bucket": "johnsmith" },
["starts-with", "$key", "user/eric/"]
]
}
Post policy中必须包含expiration和condtions。
Expiration
Expiration项指定了policy的过期时间,以ISO8601 GMT时间表示。例如”2014-12-01T12:00:00.000Z”指定了Post请求必须发生在2014年12月1日12点之前。
Conditions
Conditions是一个列表,可以用于指定Post请求的表单域的合法值。注意:表单域对应的值在检查policy之后进行扩展,因此,policy中设置的表单域的合法值应当对应于扩展之前的表单域的值。例如,如果设置key表单域为user/user1/${filename},用户的文件名为a.txt,则Post policy应当设置成[“eq”, “$key”, “user/user1/\${filename}”],而不是[“eq”, “$key”,“$key”, “user/user1/a.txt”]。Policy中支持的conditions项见下表:
如果Post请求中包含其他的表单域,可以将这些额外的表单域加入到policy的conditions中,conditions不涉及的表单域将不会进行合法性检查。
Conditions匹配方式
转义字符
于在 Post policy 中 $ 表示变量,所以如果要描述 $,需要使用转义字符\$。除此之外,JSON 将对一些字符进行转义。下图描述了 Post policy 的 JSON 中需要进行转义的字符。
Post Signature
对于验证的Post请求,HTML表单中必须包含policy和Signature信息。policy控制请求中那些值是允许的。计算Signature的具体流程为:
- 创建一个 UTF-8 编码的 policy。
- 将 policy 进行 base64 编码,其值即为 policy 表单域该填入的值,将该值作为将要签名的字符串。
- 使用 AccessKeySecret 对要签名的字符串进行签名,签名方法与Head中签名的计算方法相同(将要签名的字符串替换为 policy 即可)。
示例 Demo
- Web 端表单直传 OSS 示例 Demo:点击这里