Post Object
若用户需通过 HTML 表单上传的方式向 Bucket 上传一个 Object,可调用该接口。
使用须知
-
此操作要求请求者对 Bucket 拥有可写权限。
-
该方式开发难度较小,但是由于浏览器自身的限制,没有断点续传、上传进度等用户友好的功能。因此当文件大于 20M 或多个文件上传时,不建议使用该接口。
-
若指定的 Bucket 被设置为匿名用户可写,则请求中可不携带用户认证信息
-
若指定的 Bucket 被设置为匿名用户可写,请求中仍然携带了用户认证信息,则 山河云对象存储仍然会对该用户进行认证,当 山河云对象存储认证该用户不拥有该 Bucket 的可写权限,该请求返回错误。
-
若同时有多个上传请求写入同一个对象名称,则最后一个被 山河云对象存储处理的请求会覆盖之前上传的对象内容。
-
HTML 的表单设置如下:
action
为http://<bucket-name>.jn1.is.shanhe.com
,其中zone-id
可参考 Zone
method
必须为POST
enctype
必须为multipart/form-data
Object key 在表单项中设置。 -
考虑到不是所有网站都默认使用 UTF-8,若您的网站需要以 GBK 或 Big5 展示,我们支持在
Form
中声明charset
字段来定义客户端上传的文件名所用编码。山河云对象存储服务端在接收到之后,会将其转换为 UTF-8 的格式来存储,以便兼容跨平台的客户端。但由于不是所有字符都能对应到 UTF-8 码表,转换过程仍有可能出现乱码,所以 山河云对象存储建议用户最好使用 UTF-8 来作为上传编码。
请求语法
POST / HTTP/1.1
Host: <bucket-name>.jn1.is.shanhe.com
Content-Type: multipart/form-data; boundary=XXXXXX
Content-Length: length
请求参数
无。
请求消息头
此接口仅包含公共请求头。关于公共请求头的更多信息,请参见公共请求头。
表单项字段
表单字段 | 类型 | 描述 | 是否必须 |
---|---|---|---|
access_key_id |
String |
Access Key ID。若该 Bucket 没有公开写权限,或含有 |
否 |
signature |
String |
签名认证信息。用 Secret Key 对 base64 编码后的 |
否 |
content-type |
String |
指定上传的文件类型,若用户上传的文件类型与本设置不一致,返回错误。 |
否 |
charset |
String |
指定上传的文件名的编码方式。必须与网页开头的 |
否 |
key |
String |
上传文件的 Object Key。有如下限制:
|
是 |
policy |
String |
设置上传文件的访问策略,由多个表单项组成。规则如下:
|
否 |
redirect |
String |
请求结果重定向 URL。
|
否 |
file |
Binary |
待上传的文件,必须作为最后一个有效表单项。位于该项后面的表单项将被丢弃,故,该项后面的表单项不能作为签名的部分。 |
是 |
x-qs-storage-class |
String |
指定该对象的存储级别。默认值为
|
否 |
备注:
请求消息体
无。
响应头
此接口仅包含公共响应头。关于公共响应头的更多信息,请参见公共响应头。
错误码
该 API 为幂等操作. 上传成功返回 201; 假如有重定向则返回 302. 失败的返回码参考错误码列表。
示例
Signature 字段示例:
import hmac
import json
from hashlib import sha256
from base64 import b64encode
policy_json = {
"key": "user/tom/${filename}",
"redirect": "http://<mydomain>.com/callback",
"charset": "UTF-8"
}
policy = b64encode(json.dumps(policy_json))
h = hmac.new(YOUR_SECRET_KEY, digestmod=sha256)
h.update(policy)
signature = b64encode(h.digest()).strip()
HTML 上传对象:
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<h3>Upload</h3>
<form action="http://<bucket-name>.jn1.is.shanhe.com" method="POST" enctype="multipart/form-data">
<input type=hidden name="policy" value="eyJrZXkiOiAidXNlci90b20vJHtmaWxlbmFtZX0iLCAicmVkaXJlY3QiOiAiaHR0cDovL215ZG9tYWluLmNvbS9jYWxsYmFjayJ9" />
<input type=hidden name="access_key_id" value="YYY" />
<input type=hidden name="signature" value="XXX" />
<input type=hidden name="key" value="user/tom/${filename}"/>
<input type=hidden name="charset" value="UTF-8" /> <!-- 该网页为UTF-8 -->
<input type=hidden name="redirect" value="http://<mydomain>.com/callback"/>
<input type=file name="file" />
<input type=submit name="Upload" value="Upload to QingStor" />
</form>
</html>
Policy 字段示例:
未编码的 JSON 格式 policy 如下:
{"key": "user/tom/${filename}", "redirect": "http://.com/callback"}
对应的 base64 编码后的 policy 为:
eyJrZXkiOiAidXNlci90b20vJHtmaWxlbmFtZX0iLCAicmVkaXJlY3QiOiAiaHR0cDovLzxteWRvbWFpbj4uY29tL2NhbGxiYWNrIn0=
请求示例
POST / HTTP/1.1
Host: .jn1.is.shanhe.com
User-Agent: curl/7.30
Content-Type: multipart/form-data; boundary=1234567890
Content-Length: length
--1234567890
Content-Disposition: form-data; name="access_key_id"
YYY
--1234567890
Content-Disposition: form-data; name="policy"
eyJrZXkiOiAidXNlci90b20vJHtmaWxlbmFtZX0iLCAicmVkaXJlY3QiOiAiaHR0cDovLzxteWRvbWFpbj4uY29tL2NhbGxiYWNrIn0=
--1234567890
Content-Disposition: form-data; name="signature"
XXX
--1234567890
Content-Disposition: form-data; name="key"
user/tom/${filename}
--1234567890
Content-Disposition: form-data; name="redirect"
http://.com/callback
--1234567890
Content-Disposition: form-data; name="file"; filename="icon.jpg"
Content-Type: image/jpeg
file_content
--1234567890
Content-Disposition: form-data; name="Upload"
Upload to QingStor
--1234567890--
响应示例
HTTP/1.1 302 Found
Server: QingStor
Date: Sun, 16 Aug 2015 09:05:00 GMT
ETag: "0c2f573d81194064b129e940edcefe9b"
Content-Length: 0
Connection: close
x-qs-request-id: aa08cf7a43f611e5886952542e6ce14b
Location: http://.com/callback?status=201&code=created&message=Object+created&request_id=aa08cf7a43f611e5886952542e6ce14b
SDK
此接口所对应的各语言 SDK 可参考 SDK 文档。
内置变量
名字 | 描述 |
---|---|
filename |
用户上传文件的文件名,默认为空。若该文件名中包含有目录,则仅需保留最后一个 |