post object消息包括消息头(header)和消息体(body)。header和body之间,由<code>\r\n--{boundary}</code>分割。body由一系列的表单域构成,表单域格式如下 <code>content-disposition: form-data; name="{key}"\r\n\r\n{value}\r\n--{boundary}</code>。 常见的header有host、user-agent、content-length、content-type、content-md5等,表单域字段有key、ossaccesskeyid、signature、content-disposition、object meta(x-oss-meta-*)、x-oss-security-token、其它http header(cache-control/content-type/cache-control/content-type/content-disposition/content-encoding/expires/content-encoding/expires)、file等。表单域中<code>file</code>必须是最后一个。
postobject常见错误见下表:
序号
错误
原因
解法
1
errorcode: malformedpostrequest
errormessage: the body of your post request is not well-formed multipart/form-data
表单域格式不符合要求
表单域格式请参看表后的<code>putobject表单域格式</code>
2
errorcode: invalidaccesskeyid
errormessage: the oss access key id you provided does not exist in our records.
<code>accesskeyid</code>禁用或不存在,或者过期的临时用户accesskeyid,或者临时用户没有提供sts token
3
errorcode: accessdenied
errormessage: invalid according to policy: policy expired.
表单域policy中的<code>expiration</code>过期
请调整policy中的<code>expiration</code>,注意expiration的格式 iso8601 gmt
4
errormessage: signaturedoesnotmatch the request signature we calculated does not match the signature you provided. check your key and signing method.
签名错误
签名方法请参看下面的<code>putobject中的签名</code>
5
errorcode: invalidpolicydocument
errormessage: invalid policy: invalid simple-condition: simple-conditions must have exactly one property specified.
请求中policy至少包含一个condition
请参看表后的 <code>putobject中的policy格式</code>
6
errormessage: invalid policy: invalid json: unknown char e
请求中的<code>policy</code>格式不正确
请检查policy格式,<code>"</code>是否加缺失,转义字符是否加<code>\</code>
7
errormessage: invalid policy: invalid json: , or ] expected
policy中是否缺少 <code>,</code> 或 <code>]</code>
8
errormessage: invalid according to policy: policy condition failed: ["starts-with", "$key", "user/eric/"]
请求指定的<code>key</code>与<code>policy</code>限定的不符
请检查请求中表单域<code>key</code>的值
9
errormessage: invalid according to policy: policy condition failed: ["eq", "$bucket", "mingdi-bjx"]
请求指定<code>bucket</code>与<code>policy</code>限定的不符
请检查endpoint中的<code>bucket</code>的值
10
errormessage: invalid according to policy: policy condition failed: ["starts-with", "$x-oss-meta-prop", "prop-"]
请求指定的文件元数据<code>x-oss-meta-prop</code>与policy限定的不符
请检查请求中的<code>x-oss-meta-prop</code>的值
11
errormessage: invalid according to policy: policy condition failed: ["eq", "${field}", "${value}"]
表单域中指定的<code>{field}</code>与policy中限定的值不符,或者在请求中没有指定
请检查请求中的<code>{field}</code>的值
12
errormessage: you have no right to access this object because of bucket acl.
当前用户无权限
13
errorcode: invalidargument
errormessage: the bucket post must contain the specified 'key'. if it is specified, please check the order of the fields
表单域没有指定<code>key</code>,或者放在了表单域<code>file</code>后
请添加表单域<code>key</code>或调整顺序
putobject请求格式,有以下注意点:
header一定要有 <code>content-type: multipart/form-data; boundary={boundary}</code> ;
header和body之间由 <code>\r\n--{boundary}</code> 分割 ;
表单域格式 <code>content-disposition: form-data; name="{key}"\r\n\r\n{value}\r\n--{boundary}</code> ;
表单域 <code>file</code> 必须为最后一个表单域;
表单域名称大小写敏感,如policy、key、file、ossaccesskeyid、ossaccesskeyid、content-disposition;
bucket为 <code>public-read-write</code> 时,可以不指定表单域ossaccesskeyid、policy、signature;一旦指定ossaccesskeyid、policy、 signature中的任意一个,无论bucket是否为public-read-write,则另两个必须指定。
下面是postobject请求的示例:
提示: 上面示例请求中<code>\r\n</code>显示为新行,即换行,后面的示例请求类似;
如果您还有疑问,请参考示例代码:
putobject请求的 <code>policy</code> 表单域用于验证请求的合法性,声明了putobject请求必须满足的条件。限定条件为 utf-8格式的json文本,经过base64编码后放在表单域policy中。 policy中必须包含expiration和condtions,其中condtions至少有一项。下面是base64编码前的policy示例:
<code>expiration</code>项指定了请求的过期时间, iso8601 gmt 时间格式;如 <code>2018-01-01t12:00:00.000z</code>指定请求必须发生在2018年1月1日12点前。
post policy的支持的限定条件(conditions)如下:
名称
描述
示例
bucket
上传文件的bucket名称。支持精确匹配方式。
{"bucket": "johnsmith" } 或 ["eq", "$bucket", "johnsmith"]
key
上传文件的名称。支持精确匹配和前缀匹配方式。
["starts-with", "$key", "user/etc/"]
content-length-range
上传文件允许的最小、最大长度。
["content-length-range", 0, 104857600]
x-oss-meta-*
指定的object meta。支持精确匹配和前缀匹配方式。
["starts-with", "$x-oss-meta-prop", "prop-"]
success_action_redirect
上传成功后的跳转url地址。支持精确匹配和前缀匹配方式。
["starts-with", "$success_action_redirect", "http://www.aliyun.com"]
success_action_status
未指定success_action_redirect时,上传成功后的返回状态码。支持精确匹配和前缀匹配方式。
["eq", "$success_action_status", "204"]
cache-control, content-type, content-disposition, content-encoding, expires等
http请求头,作为表单域传递。支持精确匹配和前缀匹配方式。
["eq", "$content-encoding", "zlib"]
post policy有以下转义字符,使用 <code>\</code> 转义。
转义字符
/
斜杠
\
反斜杠
"
双引号
$
美元符
b
空格
f
换页
n
换行
r
回车
t
水平制表符
uxxxx
unicode字符
对于验证的post请求,请求中必须包含accesskeyid、policy、signature表单域。计算签名的流程如下:
创建一个<code>utf-8</code>编码的policy。
将policy进行<code>base64</code>编码,其值即为policy表单域该填入的值,将该值作为将要签名的字符串。
即:
计算出的签名在表单域<code>signature</code>中指定,如下所示:
key即object name,在表单域<code>key</code>中指定,示例如下:
object内容通过表单域<code>file</code>中指定,示例如下
注意: 表单域<code>file</code>必须是表单中的最后一个域,即表单域<code>file</code>必须放在所有表单域后; <code>filename</code>是上传的本地文件名称,而不是object name。
object类型在表单域<code>file</code>中指定<code>content-type</code>,而不是header中的<code>content-type</code>,示例如下:
在postobject请求头中指定<code>content-md5</code>,注意md5值是整个body的md5,即所有表单域的md5。请求header示例如下:
签名的计算方法请参看 <code>putobject中的签名</code> , 签名通过表单域 <code>signature</code> 携带。
临时用户密钥的accesskeyid、accesskeysecret用法跟主用户、子用户相同,token放在表单域 <code>x-oss-security-token</code> 中携带。示例如下:
上传回调(callback)通过表单域<code>callback</code>携带。示例如下:
callback的自定义参数也是通过表单域携带。示例如下:
在表单域<code>file</code>中指定<code>content-transfer-encoding</code>。<code>file</code>表单域示例如下:
用户自定义元信息,可以表单域指定,示例如下:
oss的postobject支持丰富的条件限制,可以满足高安全性要求。限定条件conditions可以通过表单域 <code>policy</code> 指定,详细的说明请参看上面的 <code>putobject中的policy格式</code> 。下面是一个policy的示例:
上面的policy,限定用户的postobject操作:<code>bucket</code> 必须是 <code>md-hz</code>,<code>key</code> 必须以<code>md/conf/</code> 开头,是上传的文件长度必须在100m以下;且请求时间在 <code>2018-01-01t12:00:00.000z</code>之前。
<a href="https://github.com/aliyun/aliyun-oss-csharp-sdk/blob/master/samples/samples/postpolicysample.cs">c# post demo</a>
<a href="https://github.com/aliyun/aliyun-oss-java-sdk/blob/master/src/samples/postobjectsample.java">java post demo</a>
<a href="https://help.aliyun.com/document_detail/31925.html">js post demo</a>