閱讀353 返回首頁    go 小米MIX


PostObject錯誤及排查___常見錯誤及排除_最佳實踐_對象存儲 OSS-阿裏雲

PostObject簡介

PostObject使用表單上傳文件到OSS。PostObject的消息實體通過 多重表單格式multipart/form-data 編碼,詳細說明請參看 RFC 2388。Put Object中參數通過HTTP請求頭傳遞,Post Object參數則作為消息體的表單域傳遞。

Post Object消息包括消息頭(Header)和消息體(Body)。Header和Body之間,由rn--{boundary}分割。Body由一係列的表單域構成,表單域格式如下: Content-Disposition: form-data; name="{key}"rnrn{value}rn--{boundary}。 常見的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等。表單域中file必須是最後一個。

更多詳細的介紹請參看 Post Object

PostObject常見錯誤

PostObject常見錯誤見下表:

序號 錯誤 原因 解法
1 ErrorCode: MalformedPOSTRequest
ErrorMessage: The body of your POST request is not well-formed multipart/form-data
表單域格式不符合要求 表單域格式請參看表後的 PutObject表單域格式
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.
簽名錯誤 簽名方法請參看下麵的 PutObject的簽名
5 ErrorCode: InvalidPolicyDocument
ErrorMessage: Invalid Policy: Invalid Simple-Condition: Simple-Conditions must have exactly one property specified.
請求中policy至少包含一個condition 請參看表後的 PutObject的Policy格式
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-prop與policy限定的不符 請檢查請求中的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權限問題及排查

PutObject表單域格式

PutObject請求格式,有以下注意點:

  • Header一定要有 Content-Type: multipart/form-data; boundary={boundary}
  • Header和body之間由 rn--{boundary} 分割。
  • 表單域格式 Content-Disposition: form-data; name="{key}"rnrn{value}rn--{boundary}
  • 表單域 file 必須為最後一個表單域。
  • 表單域名稱大小寫敏感,如policy、key、file、OSSAccessKeyId、OSSAccessKeyId、Content-Disposition。
  • Bucket為 public-read-write 時,可以不指定表單域OSSAccessKeyId、policy、Signature;一旦指定OSSAccessKeyId、policy、 Signature中的任意一個,無論bucket是否為public-read-write,則另兩個必須指定。

下麵是PostObject請求的示例:

  1. POST / HTTP/1.1
  2. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)
  3. Content-Type: multipart/form-data; boundary=9431149156168
  4. Host: mingdi-hz.oss-cn-hangzhou.aliyuncs.com
  5. Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
  6. Connection: keep-alive
  7. Content-Length: 5052
  8. --9431149156168
  9. Content-Disposition: form-data; name="key"
  10. test-key
  11. --9431149156168
  12. Content-Disposition: form-data; name="Content-Disposition"
  13. attachment;filename=D:img1.png
  14. --9431149156168
  15. Content-Disposition: form-data; name="OSSAccessKeyId"
  16. 2NeL********j2Eb

提示:

  • 上麵示例請求中rn顯示為新行,即換行,後麵的示例請求類似。
  • 上麵的示例為請求的部分內容,完整的請求請參看 Post Object

如果您還有疑問,請參考示例代碼: 

PutObject的Policy格式

PutObject請求的 policy 表單域用於驗證請求的合法性,聲明了PutObject請求必須滿足的條件。限定條件為:

  • UTF-8格式的Json文本,經過base64編碼後放在表單域policy中。
  • Policy中必須包含expiration和condtions,其中condtions至少有一項。

下麵是base64編碼前的policy示例:

  1. {
  2. "expiration": "2018-01-01T12:00:00.000Z",
  3. "conditions": [
  4. ["content-length-range", 0, 104857600]
  5. ]
  6. }

expiration項指定了請求的過期時間, ISO8601 GMT 時間格式;如 2018-01-01T12:00:00.000Z指定請求必須發生在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”, “https://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

PutObject的簽名

對於驗證的Post請求,請求中必須包含AccessKeyID、policy、Signature表單域。計算簽名的流程如下:

  1. 創建一個UTF-8編碼的policy。
  2. 將policy進行base64編碼,其值即為policy表單域該填入的值,將該值作為將要簽名的字符串。
  3. 使用AccessKeySecret對要簽名的字符串進行簽名,先用hmac-sha1哈希,再base64編碼;簽名方法與 Header簽名 的方法相同。

即:

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

計算出的簽名在表單域Signature中指定,如下所示:

  1. Content-Disposition: form-data; name="Signature"
  2. {signature}
  3. --9431149156168

如果您還有疑問,請參考示例代碼: 

常見問題

怎麼指定key?

key即object name,在表單域key中指定,示例如下:

  1. Content-Disposition: form-data; name="key"
  2. {key}
  3. --9431149156168

怎麼指定object內容?

Object內容通過表單域file中指定,示例如下:

  1. Content-Disposition: form-data; name="file"; filename="images.png"
  2. Content-Type: image/png
  3. {file-content}
  4. --9431149156168

注意:

  • 表單域file必須是表單中的最後一個域,即表單域file必須放在所有表單域後。
  • filename是上傳的本地文件名稱,而不是object name。

怎麼指定object類型content-type?

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

  1. Content-Disposition: form-data; name="file"; filename="images.png"
  2. Content-Type: image/png
  3. {file-content}
  4. --9431149156168

怎麼指定object內容md5校驗content-md5?

在PostObject請求頭中指定Content-MD5,注意MD5值是整個body的MD5,即所有表單域的MD5。請求Header示例如下:

  1. POST / HTTP/1.1
  2. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)
  3. Content-Type: multipart/form-data; boundary=9431149156168
  4. Content-MD5: tdqHe4hT/TuKb7Y4by+nJg==
  5. Host: mingdi-hz.oss-cn-hangzhou.aliyuncs.com
  6. Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
  7. Connection: keep-alive
  8. Content-Length: 5246
  9. --9431149156168

怎麼指定簽名Signature?

簽名的計算方法請參看 PutObject中的簽名 , 簽名通過表單域 Signature 攜帶。

怎麼使用臨時用戶STS Token執行PostOject?

臨時用戶密鑰的AccessKeyID、AccessKeySecret用法跟主用戶、子用戶相同,Token放在表單域 x-oss-security-token 中攜帶。示例如下:

  1. Content-Disposition: form-data; name="Signature"
  2. 5L0+KaeugxYygfqWLJLoy0ehOmA=
  3. --9431149156168
  4. Content-Disposition: form-data; name="x-oss-security-token"
  5. {Token}
  6. --9431149156168

提示:如果您想更多了解更多訪問控製的信息,請參看 阿裏雲訪問控製

怎麼指定上傳回調(callback)?

上傳回調(callback)通過表單域callback攜帶。示例如下:

  1. Content-Disposition: form-data; name="callback"
  2. eyJjYWxsYmFja0JvZHlUeXBlIjogImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIsICJjYWxsYmFja0JvZHkiOiAiZmlsZW5hbWU9JHtvYmplY3R9JnNpemU9JHtzaXplfSZtaW1lVHlwZT0ke21pbWVUeXBlfSIsICJjYWxsYmFja1VybCI6ICJodHRwOi8vb3NzLWRlbW8uYWxpeXVuY3MuY29tOjIzNDUwIn0=
  3. --9431149156168

Callback的自定義參數也是通過表單域攜帶。示例如下:

  1. Content-Disposition: form-data; name="x:var1"
  2. {var1-value}
  3. --9431149156168

提示:如果您想了解callback更多內容,請參看 上傳回調

怎麼指定Content-Transfer-Encoding?

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

  1. Content-Disposition: form-data; name="file"; filename="images.png"
  2. Content-Type: image/png
  3. Content-Transfer-Encoding: base64
  4. {file-content}
  5. --9431149156168

怎麼指定用戶自定義元信息Object User Meta?

用戶自定義元信息,可以表單域指定,示例如下:

  1. Content-Disposition: form-data; name="x-oss-meta-uuid"
  2. {uuid}
  3. --9431149156168
  4. Content-Disposition: form-data; name="x-oss-meta-tag"
  5. {tag}
  6. --9431149156168

提示:文件元信息更詳細的說明,請參看 文件元信息Object Meta

怎麼指定限定條件expiration、Key、Bucket、size、header等?

OSS的PostObject支持豐富的條件限製,可以滿足高安全性要求。限定條件Conditions可以通過表單域 policy 指定,詳細的說明請參看上麵的 PutObject的Policy格式。下麵是一個policy的示例:

  1. {
  2. "expiration": "2018-01-01T12:00:00.000Z",
  3. "conditions": [
  4. ["eq", "$bucket", "md-hz"],
  5. ["starts-with", "$key", "md/conf/"],
  6. ["content-length-range", 0, 104857600]
  7. ]
  8. }

上麵的policy,用戶的PostObject操作的限定條件如下:

  • bucket 必須是 md-hz
  • key 必須以md/conf/ 開頭。
  • 是上傳的文件長度必須在100M以下。
  • 請求時間在 2018-01-01T12:00:00.000Z之前。

怎麼指定Cache-Control、Content-Type、Content-Disposition、 Content-Encoding、Expires等HTTP Header?

Cache-Control, Content-Type, Content-Disposition, Content-Encoding, Expires等HTTP Header需要在表單域中指定,這些HTTP Header的含義請參看 RFC2616 。但是 Content-MD5 需要在Post Header中指定。

PostObject示例

常用鏈接

最後更新:2016-12-13 21:20:06

  上一篇:go OSS 403錯誤及排查__常見錯誤及排除_最佳實踐_對象存儲 OSS-阿裏雲
  下一篇:go OSS防盜鏈(Referer)配置及錯誤排除__常見錯誤及排除_最佳實踐_對象存儲 OSS-阿裏雲