Post Object错误及排查

更新时间:2025-02-19 09:53:33

本文介绍Post Object时的常见错误及解决方法。

Post Object简介

Post Object使用表单上传文件到OSS。Post Object的消息实体通过多重表单格式multipart/form-data编码,详细说明请参看RFC 2388。PutObject中参数通过HTTP请求头传递,Post Object参数则作为消息体的表单域传递。

Post Object消息包括消息头(Header)和消息体(Body)。HeaderBody之间,由\r\n--{boundary}分割。Body由一系列的表单域构成,表单域格式如下:

Content-Disposition: form-data; name="{key}"\r\n\r\n{value}\r\n--{boundary}

常见的HeaderHost、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等。表单域中file必须是最后一个。

更多详细的介绍请参看Post Object

Post Object常见错误

Post Object常见错误见下表:

序号

错误

原因

解法

序号

错误

原因

解法

1

ErrorCode: MalformedPOSTRequest ErrorMessage: The body of your POST request is not well-formed multipart/form-data

表单域格式不符合要求

表单域格式请参看表后的 Post Object表单域格式

2

ErrorCode: InvalidAccessKeyId ErrorMessage: The OSS Access Key Id you provided does not exist in our records.

AccessKeyID禁用或不存在,或者过期的临时用户AccessKeyID,或者临时用户没有提供STS Token

排查方法请参看InvalidAccessKeyId错误排查

3

ErrorCode: AccessDenied ErrorMessage: Invalid according to Policy: Policy expired.

表单域policy中的expiration过期

请调整policy中的expiration,注意expiration的格式 ISO8601 GMT

4

ErrorCode: AccessDenied ErrorMessage: SignatureDoesNotMatch The request signature we calculated does not match the signature you provided. Check your key and signing method.

签名错误

签名方法请参看下面的Post Object的签名

5

ErrorCode: InvalidPolicyDocument ErrorMessage: Invalid Policy: Invalid Simple-Condition: Simple-Conditions must have exactly one property specified.

请求中policy至少包含一个condition

请参看表后的Post ObjectPolicy格式

6

ErrorCode: InvalidPolicyDocument ErrorMessage: Invalid Policy: Invalid JSON: unknown char e

请求中的policy格式不正确

请检查policy格式,"是否加缺失,转义字符是否加\

7

ErrorCode: InvalidPolicyDocument ErrorMessage: Invalid Policy: Invalid JSON: , or ] expected

请求中的policy格式不正确

请检查policy中是否缺少,]

8

ErrorCode: AccessDenied ErrorMessage: Invalid according to Policy: Policy Condition failed: [“starts-with”, “$key”, “user/eric/“]

请求指定的keypolicy限定的不符

请检查请求中表单域key的值

9

ErrorCode: AccessDenied ErrorMessage: Invalid according to Policy: Policy Condition failed: [“eq”, “$bucket”, “mingdi-bjx”]

请求指定bucketpolicy限定的不符

请检查endpoint中的bucket的值

10

ErrorCode: AccessDenied ErrorMessage: Invalid according to Policy: Policy Condition failed: [“starts-with”, “$x-oss-meta-prop”, “prop-“]

请求指定的文件元数据x-oss-meta-proppolicy限定的不符

请检查请求中的x-oss-meta-prop的值

11

ErrorCode: AccessDenied ErrorMessage: Invalid according to Policy: Policy Condition failed: [“eq”, “${field}”, “${value}”]

表单域中指定的{field}policy中限定的值不符,或者在请求中没有指定

请检查请求中的{field}的值

12

ErrorCode: AccessDenied ErrorMessage: You have no right to access this object because of bucket acl.

当前用户无权限

请参看OSS权限问题及排查

13

ErrorCode: InvalidArgument ErrorMessage: The bucket POST must contain the specified ‘key’. If it is specified, please check the order of the fields

表单域没有指定key,或者放在了表单域file

请添加表单域key或调整顺序

  • Post Object表单域格式

    Post Object请求格式,有以下注意点:

    • Header一定要有Content-Type: multipart/form-data; boundary={boundary}

    • Headerbody之间由\r\n--{boundary} 分割。

    • 表单域格式 :

      Content-Disposition: form-data;
              name="{key}"\r\n\r\n{value}\r\n--{boundary}
    • 表单域名称大小写敏感,如policy、key、file、OSSAccessKeyId、OSSAccessKeyId、Content-Disposition。

      重要

      表单域file必须为最后一个表单域。

    • Bucketpublic-read-write时,可以不指定表单域OSSAccessKeyId、policy、Signature,一旦指定OSSAccessKeyId、policy、 Signature中的任意一个,无论bucket是否为public-read-write,则另两个必须指定。

    下面是Post Object请求的示例:

    POST / HTTP/1.1
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)
    Content-Type: multipart/form-data; boundary=9431149156168
    Host: mingdi-hz.oss-cn-hangzhou.aliyuncs.com
    Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
    Connection: keep-alive
    Content-Length: 5052
    --9431149156168
    Content-Disposition: form-data; name="key"
    test-key
    --9431149156168
    Content-Disposition: form-data; name="Content-Disposition"
    attachment;filename=D:\img\1.png
    --9431149156168
    Content-Disposition: form-data; name="OSSAccessKeyId"
    2NeL********j2Eb
    说明
    • 上面示例请求中\r\n显示为新行,即换行,后面的示例请求类似。

    • 上面的示例为请求的部分内容,完整的请求请参看Post Object

    如果您还有疑问,请参考示例代码:

  • Post ObjectPolicy格式

    Post Object请求的policy表单域用于验证请求的合法性,声明了Post Object请求必须满足的条件。限定条件为:

    • UTF-8格式的JSON文本,经过base64编码后放在表单域policy中。

    • Policy中必须包含expirationcondtions,其中condtions至少有一项。

    下面是base64编码前的policy示例:

    {
        "expiration": "2018-01-01T12:00:00.000Z",
        "conditions": [
            ["content-length-range", 0, 104857600]
        ]
    }

    expiration项指定了请求的过期时间, ISO8601 GMT 时间格式;如 2018-01-01T12:00:00.000Z指定请求必须发生在20181112点前。

    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有以下转义字符,使用 \ 转义。

    转义字符

    描述

    转义字符

    描述

    /

    斜杠

    \

    反斜杠

    双引号

    $

    美元符

    \b

    空格

    \f

    换页

    \n

    换行

    \r

    回车

    \t

    水平制表符

    \uxxxx

    Unicode字符

    Post Policy更详细的说明,请参考 Post Policy

  • Post Object的签名

    对于验证的Post请求,请求中必须包含AccessKeyID、policy、Signature表单域。计算签名的流程如下:

    1. 创建一个UTF-8编码的policy。

    2. policy进行base64编码,其值即为policy表单域该填入的值,并将该值作为将要签名的字符串。

    3. 使用AccessKeySecret对要签名的字符串进行签名,先用hmac-sha1哈希,再base64编码;签名方法与Header签名的方法相同。

    即:

    Signature = base64(hmac-sha1(AccessKeySecret, base64(policy)))

    计算出的签名在表单域Signature中指定,如下所示:

    Content-Disposition: form-data; name="Signature"
    {signature}
    --9431149156168

    如果您还有疑问,请参考示例代码:

常见问题

  • 怎么指定key?

    keyobject name,在表单域key中指定,示例如下:

    Content-Disposition: form-data; name="key"
    {key}
    --9431149156168
  • 怎么指定object内容?

    Object内容通过表单域file中指定,示例如下:

    Content-Disposition: form-data; name="file"; filename="images.png"
    Content-Type: image/png
    {file-content}
    --9431149156168
    说明
    • 表单域file必须是表单中的最后一个域,即表单域file必须放在所有表单域后。

    • filename是上传的本地文件名称,而不是object name。

  • 怎么指定object类型content-type?

    Object类型在表单域file中指定Content-Type,而不是Header中的Content-Type,示例如下:

    Content-Disposition: form-data; name="file"; filename="images.png"
    Content-Type: image/png
    {file-content}
    --9431149156168
  • 怎么指定object内容md5校验content-md5?

    Post Object请求头中指定Content-MD5,注意MD5值是整个bodyMD5,即所有表单域的MD5。请求Header示例如下:

    POST / HTTP/1.1
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)
    Content-Type: multipart/form-data; boundary=9431149156168
    Content-MD5: tdqHe4hT/TuKb7Y4by+nJg==
    Host: mingdi-hz.oss-cn-hangzhou.aliyuncs.com
    Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
    Connection: keep-alive
    Content-Length: 5246
    --9431149156168
  • 怎么指定签名Signature?

    签名的计算方法请参看PostObject中的签名 , 签名通过表单域Signature携带。

  • 怎么使用临时用户STS Token执行Post Object?

    临时用户密钥的AccessKeyID、AccessKeySecret用法跟主用户、子用户相同,Token放在表单域x-oss-security-token中携带。示例如下:

    Content-Disposition: form-data; name="Signature"
    5L0+KaeugxYygfqWLJLoy0ehOmA=
    --9431149156168
    Content-Disposition: form-data; name="x-oss-security-token"
    {Token}
    --9431149156168
  • 怎么指定上传回调(callback)?

    上传回调(callback)通过表单域callback携带。示例如下:

    Content-Disposition: form-data; name="callback"
    eyJjYWxsYmFja0JvZHlUeXBlIjogImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIsICJjYWxsYmFja0JvZHkiOiAiZmlsZW5hbWU9JHtvYmplY3R9JnNpemU9JHtzaXplfSZtaW1lVHlwZT0ke21pbWVUeXBlfSIsICJjYWxsYmFja1VybCI6ICJodHRwOi8vb3NzLWRlbW8uYWxpeXVuY3MuY29tOjIzNDUwIn0=
    --9431149156168

    Callback的自定义参数也是通过表单域携带。示例如下:

    Content-Disposition: form-data; name="x:var1"
    {var1-value}
    --9431149156168
    说明

    如果您想了解callback更多内容,请参看上传回调

  • 怎么指定Content-Transfer-Encoding?

    在表单域file中指定Content-Transfer-Encodingfile表单域示例如下:

    Content-Disposition: form-data; name="file"; filename="images.png"
    Content-Type: image/png
    Content-Transfer-Encoding: base64
    {file-content}
    --9431149156168
  • 怎么指定用户自定义元信息Object User Meta?

    用户自定义元信息,可以通过表单域指定,示例如下:

    Content-Disposition: form-data; name="x-oss-meta-uuid"
    {uuid}
    --9431149156168
    Content-Disposition: form-data; name="x-oss-meta-tag"
    {tag}
    --9431149156168
    说明

    文件元信息更详细的说明,请参看文件元信息Object Meta

  • 怎么指定限定条件expiration、Key、Bucket、size、header等?

    OSSPost Object支持丰富的条件限制,可以满足高安全性要求。限定条件Conditions可以通过表单域policy 指定,详细的说明请参看上面的Post ObjectPolicy格式。下面是一个policy的示例:

    {
        "expiration": "2018-01-01T12:00:00.000Z",
        "conditions": [
            ["eq", "$bucket", "md-hz"],
            ["starts-with", "$key", "md/conf/"],
            ["content-length-range", 0, 104857600]
        ]
    }

    上面的policy实例中,用户的Post Object操作的限定条件如下:

    • bucket必须是md-hz

    • key必须以md/conf/开头。

    • 上传的文件长度必须在100M以下。

    • 请求时间在2018-01-01T12:00:00.000Z之前。

  • 怎么指定Cache-Control、Content-Type、Content-Disposition、Content-Encoding、ExpiresHTTP Header?

    Cache-ControlContent-TypeContent-Disposition、Content-EncodingExpiresHTTP Header需要在表单域中指定,这些HTTP Header的含义请参看RFC2616 。但是Content-MD5需要在Post Header中指定。

Post Object示例

常用链接

  • 本页导读 (1)
  • Post Object简介
  • Post Object常见错误
  • 常见问题
  • Post Object示例
  • 常用链接