
# 回调-Callback
#### 功能介绍
用户可以在上传对象请求中设置回调参数，OBS在对象上传成功之后，将上传结果回调特定服务器，并将回调结果返回给用户。了解更多回调相关信息请参考[使用上传回调获取对象信息](https://support.huaweicloud.com/usermanual-obs/obs_41_0079.html)。
#### 接口约束
- 目前只在POST上传对象、PUT上传对象以及合并段API中支持回调功能。
- 在对象上传成功之后才会回调特定服务器，如果对象上传失败则不会回调。
- 如果上传的图片大小超过25M，则无法通过imageInfo相关系统变量获取图片基本信息，会导致回调失败。

- 回调成功，返回回调结果给客户端，同时将上传对象的Etag以头域返回，当回调结果也包含Etag时，将对Etag拼接后返回。回调失败，返回203，表示对象上传成功但是回调失败。
- 回调请求必须在20秒内响应，超时将视为失败。
 
#### 授权信息
回调功能不需要额外权限，仅需对应上传操作的权限，例如[POST上传对象](https://support.huaweicloud.com/api-obs/obs_04_0081.html)、[PUT上传对象](https://support.huaweicloud.com/api-obs/obs_04_0080.html)接口的权限。
#### POST上传回调
POST上传对象API中，回调参数可以在表单中携带，也可以在policy中携带，**两者只能选择其一** ：
- 表单携带：每个回调参数都**需要增加** 一个表单元素，回调参数可以不做条件校验，即不需要在policy的conditions中增加回调参数。这种方式支持在回调消息体中使用**用户自定义变量** ，自定义变量通过"x:"前缀携带。通过表单携带的回调参数如[表1]所示。
- policy携带：**不需要增加** 表单元素。但是**不支持用户自定义变量** **，仅能使用系统变量** 。通过policy携带的回调参数如[表1]所示。
 
#### POST上传回调请求消息样式
通过表单携带回调参数的请求消息样式与POST上传对象相同，参考[POST上传-PostObject](https://support.huaweicloud.com/api-obs/obs_04_0081.html)。policy的内容包含失效时间和条件元素，参考[基于浏览器上传的表单中携带签名](https://support.huaweicloud.com/api-obs/obs_04_0012.html)。
通过policy携带回调参数的policy如下所示，比普通的policy增加了回调参数"callback"。请求消息样式与POST上传对象相同，参考[POST上传-PostObject](https://support.huaweicloud.com/api-obs/obs_04_0081.html)。
```
{ "expiration": "2017-12-31T12:00:00.000Z",
  "conditions": [
    {"x-obs-acl": "public-read" },
    {"x-obs-security-token": "YwkaRTbdY8g7q...." },
    {"bucket": "book" },
    ["starts-with", "$key", "user/"]
  ],
  "callback": [
    {"url": "http://www.example.com/callback" },
    {"host": "www.example.com" },
    {"body": "eyJrZXkiOiIkKGtleSkiLCJoYXNoIjoiJChldGFnKSJ9"},
    {"body-type": "application/json"}
  ]
}
```
#### POST上传使用表单携带回调参数
使用**表单携带** 回调参数时，回调参数如[表1]所示：
 表1表单回调参数 
| 参数名称             | 是否必选       | 类型     | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
|:---|:---|:---|:---|
| callbackUrl      | 使用回调功能时，必选 | String | **参数解释：** 对象上传成功之后，OBS向此url发送回调请求，请求方法为POST。支持设置多个url，以英文分号（;）分隔，最多支持10个。 **约束限制：** - 最多支持10个url，用英文分号分隔。  - 请求方法须为POST。  - callbackUrl必须做url编码，例如："http://www.example.com/中文?key=中文名"需要编码成"http://www.example.com/%E4%B8%AD%E6%96%87?key=%E4%B8%AD%E6%96%87%E5%90%8D"。   **取值范围：** 合法的URL地址。 **默认取值：** 不涉及。 |
| callbackHost     | 否          | String | **参数解释：** 发起回调请求的Host头域的值，如果不设置，会使用callbackUrl解析出来的Host。 **约束限制：** 不涉及。 **取值范围：** 合法的域名。 **默认取值：** 使用callbackUrl解析出来的Host。                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| callbackBody     | 是          | String | **参数解释：** 发起回调请求的body体。 回调body体支持系统变量和自定义变量，系统变量如[表3]所示，自定义变量就是以x:开头的变量。例如：key=$(key)\&hash=$(etag)\&fileid=$(x:fileid)，其中变量key、etag是系统变量，x:fileid是自定义变量。如果用户上传的对象是图片，可以在参数中设置imageInfo.width和imageInfo.height表示该图片的宽高。例如：key=$(key)\&hash=$(etag)\&w=$(imageInfo.width)\&h=$(imageInfo.height)。 **约束限制：** Body体格式必须符合callbackBodyType中设置的媒体类型；支持系统变量和自定义变量（以x:开头）。 **取值范围：** 支持系统变量和自定义变量，系统变量如[表3]所示，自定义变量就是以x:开头的变量。 **默认取值：** 不涉及。   |
| callbackBodyType | 否          | String | **参数解释：** 发起回调请求的Content-Type头域的值。 **约束限制：** 需要与callbackBody的实际格式保持一致。 **取值范围：** - application/x-www-form-urlencoded：HTML表单的默认编码格式。  - application/json：JSON 格式的字符串。   **默认取值：** application/json                                                                                                                                                                                                  |
| x:\*             | 否          | String | **参数解释：** 用户自定义变量，必须以 x: 开头。 **约束限制：** - 必须以 x: 开头。  - 仅POST表单上传方式支持自定义变量，PUT上传和合并段不支持   **取值范围：** 不涉及。 **默认取值：** 不涉及。                                                                                                                                                                                                                                                                              |
   
#### POST上传使用policy携带回调参数
使用**policy携带** 回调参数时，回调参数如[表1]所示：
表2policy回调参数 
| 参数名称      | 是否必选 | 类型     | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
|:---|:---|:---|:---|
| url       | 是    | String | **参数解释：** 对象上传成功之后，OBS向此url发送回调请求，请求方法为POST。支持设置多个url，以英文分号（;）分隔，最多支持10个。 **约束限制：** - 最多支持10个url，用英文分号分隔。  - 请求方法为POST。  - url必须做url编码。例如："http://www.example.com/中文?key=中文名"需要编码成"http://www.example.com/%E4%B8%AD%E6%96%87?key=%E4%B8%AD%E6%96%87%E5%90%8D"。   **取值范围：** 合法的URL地址。 **默认取值：** 不涉及。                                                                                                  |
| host      | 否    | String | **参数解释：** 发起回调请求的Host头域的值，如果不设置，会使用url解析出来的Host。 **约束限制：** 不涉及。 **取值范围：** 合法的域名。 **默认取值：** 使用url解析出来的Host。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| body      | 是    | String | **参数解释：** 发起回调请求的body体。 回调body体支持使用系统变量，系统变量如[表3]所示。例如：key=$(key)\&hash=$(etag)，其中变量key、etag是系统变量，则body参数为：a2V5PSQoa2V5KSZoYXNoPSQoZXRhZyk=，是key=$(key)\&hash=$(etag)的base64编码。如果用户上传的对象是图片，可以在参数中设置imageInfo.width和imageInfo.height表示该图片的宽高。例如：key=$(key)\&hash=$(etag)\&w=$(imageInfo.width)\&h=$(imageInfo.height)，body参数为：a2V5PSQoa2V5KSZoYXNoPSQoZXRhZykmdz0kKGltYWdlSW5mby53aWR0aCkmaD0kKGltYWdlSW5mby5oZWlnaHQp。 **约束限制：** body体格式必须符合body-type中设置的媒体类型。body的内容必须经过URL安全base64编码。 **取值范围：** 仅支持系统变量，如[表3]所示。 **默认取值：** 不涉及。 |
| body-type | 否    | String | **参数解释：** 发起回调请求的Content-Type头域的值。 **约束限制：** 不涉及。 **取值范围：** - application/x-www-form-urlencoded： HTML 表单的默认编码格式。  - application/json：表示请求体是JSON格式的字符串。   **默认取值：** application/json                                                                                                                                                                                                                                                                                                                   |
   
回调参数body体如[表3]所示：
 表3回调body体支持的系统变量 
| 变量名称      | 参数类型   | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
|:---|:---|:---|
| fname     | String | **参数解释：** 上传的原始文件名。 **约束限制：** 不涉及。 **取值范围：** 不涉及。 **默认取值：** 不涉及。                                                                                                                                                                                                                            |
| fsize     | String | **参数解释：** 文件的大小，单位为字节。名称兼容size，使用fsize或size均可，两者等效。 **约束限制：** 不涉及。 **取值范围：** 表示文件大小的字符串，内容为正整数。 **默认取值：** 不涉及。                                                                                                                                                                                |
| etag      | String | **参数解释：** 对象的ETag。 **约束限制：** 不涉及。 **取值范围：** 对象的ETag值。 **默认取值：** 不涉及。                                                                                                                                                                                                                       |
| bucket    | String | **参数解释：** 上传的对象所属的桶名。 **约束限制：** 不涉及 **取值范围：** 合法的桶名。 **默认取值：** 不涉及                                                                                                                                                                                                                                |
| key       | String | **参数解释：** 上传对象的名字。对象名是对象在存储桶中的唯一标识。对象名是对象在桶中的完整路径，路径中不包含桶名。 例如，您对象的访问地址为examplebucket.obs.cn-north-4.myhuaweicloud.com/folder/test.txt 中，对象名为folder/test.txt。 约束限制： 不涉及。 **取值范围：** 长度大于0且不超过1024的字符串。 **默认取值：** 不涉及。                          |
| ext       | String | **参数解释：** 上传文件的后缀名，通过自动检测的mimeType或者$(fname)的后缀来获取。名称兼容mimeType。 **约束限制：** 不涉及。 **取值范围：** 常见的文件后缀名字符串，如zip、jpg、png等。 **默认取值：** 不涉及。                                                                                                                                                           |
| override  | String | **参数解释：** 上传对象是否会产生覆盖。 **约束限制：** 值只会是true或false；当桶开启多版本时，始终为false。 **取值范围：** true：上传对象的对象名在桶中已存在，即会产生覆盖。 false：上传对象的对象名在桶内不存在，或桶开启了多版本控制时，不会产生覆盖写。 **默认取值：** 不涉及。                                                                                  |
| imageInfo | String | **参数解释：** 获取所上传图片的基本信息。 说明： 如果上传的图片大小超过25M，则无法通过imageInfo相关系统变量获取图片基本信息，会导致回调失败。 **约束限制：** 不涉及。 **取值范围：** 只支持上传图片的场景。 该变量包含$(imageInfo.width)和$(imageInfo.height)两个子字段，分别表示图片的宽度和高度。 **默认取值：** 不涉及。 |
   
#### 响应消息样式
```
HTTP/1.1 status_code
Content-Type: type
Server: OBS
Date: date
x-obs-request-id: request-id 
Content-Length: length
ETag: etag
```
#### POST上传对象回调示例
下面的几张表提供了一些回调请求的示例：
表4通过policy携带回调参数 
| 请求                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
|:---|:---|
| ``` POST / HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Content-Type: multipart/form-data; boundary=---------------------------7e329d630b26 Content-Length: 1597 -----------------------------7e32de17c166a Content-Disposition: form-data; name="key" file/obj1 -----------------------------7e32de17c166a Content-Disposition: form-data; name="AccessKeyId" UYNVCM2JJES4APB9FZUG -----------------------------7e32de17c166a Content-Disposition: form-data; name="policy" ewogICJleHBpcmF0aW9uIjogIjIwMjAtMTAtMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0In0sCiAgICBbImVxIiwgIiRrZXkiLCAiZmlsZS9vYmoxIl0KICBdLAogICJjYWxsYmFjayI6IFsKICAgIHsidXJsIjogImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2sifSwKICAgIHsiYm9keSI6ICJleUpyWlhraU9pSWtLR3RsZVNraUxDSm9ZWE5vSWpvaUpDaGxkR0ZuS1NKOSJ9LAogICAgeyJib2R5LXR5cGUiOiAiYXBwbGljYXRpb24vanNvbiJ9CiAgICBdCn0 -----------------------------7e32de17c166a Content-Disposition: form-data; name="signature" w0nW7iiC4Wfav9SXkU/NiSI99E8= -----------------------------7e32de17c166a Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt" Content-Type: text/plain 123456 ---------------------------7e32de17c166a Content-Disposition: form-data; name="submit" Upload -----------------------------7e32de17c166a-- ``` | 其中policy为： ``` { "expiration": "2020-10-01T12:00:00.000Z", "conditions": [ {"bucket": "examplebucket"}, ["eq", "$key", "file/obj1"] ], "callback": [ {"url": "http://www.example.com/callback"}, {"body": "eyJrZXkiOiIkKGtleSkiLCJoYXNoIjoiJChldGFnKSJ9"}, {"body-type": "application/json"} ] } ``` 回调body为： ``` {"key":"$(key)","hash":"$(etag)"} ``` 其中系统变量key=file/obj1，etag=f447b20a7fcbf53a5d5be013ea0b15af，最终回调的消息体是： ``` {"key":"file/obj1","hash":"f447b20a7fcbf53a5d5be013ea0b15af"} ``` |
   
表5通过表单携带回调参数，回调请求中只使用系统变量 
| 请求                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
|:---|:---|
| ``` POST / HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Content-Type: multipart/form-data; boundary=---------------------------7e329d630b26 Content-Length: 1597 -----------------------------7e32de17c166a Content-Disposition: form-data; name="key" file/obj1 -----------------------------7e32de17c166a Content-Disposition: form-data; name="AccessKeyId" UYNVCM2JJES4APB9FZUG -----------------------------7e32de17c166a Content-Disposition: form-data; name="policy" ewogICJleHBpcmF0aW9uIjogIjIwMjAtMTAtMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0In0sCiAgICBbImVxIiwgIiRrZXkiLCAiZmlsZS9vYmoxIl0KICBdCn0 -----------------------------7e32de17c166a Content-Disposition: form-data; name="signature" w0nW7iiC4Wfav9SXkU/NiSI99E8= -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackUrl" http://my.callback.com:8080/api/callback -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackBody" key=$(key)&hash=$(etag)&fname=$(fname)&fsize=$(size) -----------------------------7e32de17c166a Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt" Content-Type: text/plain 123456 ---------------------------7e32de17c166a Content-Disposition: form-data; name="submit" Upload -----------------------------7e32de17c166a-- ``` | 其中policy为： ``` { "expiration": "2020-10-01T12:00:00.000Z", "conditions": [ {"bucket": "examplebucket"}, ["eq", "$key", "file/obj1"] ] } ``` policy中可以不包含callbackUrl和callbackBody这两个回调参数。bucket、key为必须包含的表单元素。  回调body为： ``` key=$(key)&hash=$(etag)&fname=$(fname)&fsize=$(size) ``` 其中系统变量key=file/obj1，etag=f447b20a7fcbf53a5d5be013ea0b15af，fname=E:\\TEST_FILE\\TEST.txt，fsize=7。 最终回调的消息体是： ``` key=file/obj1&hash=f447b20a7fcbf53a5d5be013ea0b15af&fname=E:\TEST_FILE\TEST.txt&fsize=7 ``` |
   
表6通过表单携带回调参数，回调请求中使用系统变量和自定义变量，同时设置自定义元数据 
| 请求                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
|:---|:---|
| ``` POST / HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Content-Type: multipart/form-data; boundary=---------------------------7e329d630b26 Content-Length: 1597 -----------------------------7e32de17c166a Content-Disposition: form-data; name="key" file/obj1 -----------------------------7e32de17c166a Content-Disposition: form-data; name="AccessKeyId" UYNVCM2JJES4APB9FZUG -----------------------------7e32de17c166a Content-Disposition: form-data; name="policy" ewogICJleHBpcmF0aW9uIjogIjIwMjAtMTAtMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0In0sCiAgICBbImVxIiwgIiRrZXkiLCAiZmlsZS9vYmoxIl0sCgl7Ingtb2JzLW1ldGEtdGVzdDEiOiJ2YWx1ZTEifQogIF0KfQ -----------------------------7e32de17c166a Content-Disposition: form-data; name="signature" w0nW7iiC4Wfav9SXkU/NiSI99E8= -----------------------------7e32de17c166a Content-Disposition: form-data; name="x-obs-meta-test1" value1 -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackUrl" http://my.callback.com:8080/api/callback -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackBody" {"bucketName": "$(bucket)","key": "$(key)","hash": "$(etag)","id": "$(x:id)","createtime": "$(x:time)"} -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackHost" my.callback.com -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackBodyType" application/json -----------------------------7e32de17c166a Content-Disposition: form-data; name="x:id" test-example-id -----------------------------7e32de17c166a Content-Disposition: form-data; name="x:time" 2019-12-06 18:01:34 -----------------------------7e32de17c166a Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt" Content-Type: text/plain 123456 ---------------------------7e32de17c166a Content-Disposition: form-data; name="submit" Upload -----------------------------7e32de17c166a-- ``` | 其中policy为： ``` { "expiration": "2020-10-01T12:00:00.000Z", "conditions": [ {"bucket": "examplebucket"}, ["eq", "$key", "file/obj1"], {"x-obs-meta-test1":"value1"} ] } ``` policy中可以不包含callbackUrl、callbackBody、callbackHost、callbackBodyType、x:id、x:time这六个回调参数。bucket、key、x-obs-meta-test1为必须包含的表单元素。  回调body为： ``` {"bucketName": "$(bucket)","key": "$(key)","hash": "$(etag)","id": "$(x:id)","createtime": "$(x:time)"} ``` 其中系统变量bucket=examplebucket，key=file/obj1，etag=f447b20a7fcbf53a5d5be013ea0b15af，自定义变量x:id=test-example-id，x:time=2019-12-06 18:01:34。 最终回调的json消息体是： ``` {"bucketName": "examplebucket","key": "file/obj1","hash": "f447b20a7fcbf53a5d5be013ea0b15af","id": "test-example-id","createtime": "2019-12-06 18:01:34"} ``` |
   
表7通过表单携带回调参数，并且校验部分回调参数 
| 请求                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
|:---|:---|
| ``` POST / HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Content-Type: multipart/form-data; boundary=---------------------------7e329d630b26 Content-Length: 1597 -----------------------------7e32de17c166a Content-Disposition: form-data; name="key" file/obj1 -----------------------------7e32de17c166a Content-Disposition: form-data; name="AccessKeyId" UYNVCM2JJES4APB9FZUG -----------------------------7e32de17c166a Content-Disposition: form-data; name="policy" eyJleHBpcmF0aW9uIjogIjIwMjAtMTAtMDFUMTI6MDA6MDAuMDAwWiIsImNvbmRpdGlvbnMiOiBbeyJidWNrZXQiOiAiZXhhbXBsZWJ1Y2tldCJ9LFsiZXEiLCAiJGtleSIsICJmaWxlL29iajEiXSx7Ingtb2JzLW1ldGEtdGVzdDEiOiJ2YWx1ZTEifSx7ImNhbGxiYWNrVXJsIjoiaHR0cDovL215LmNhbGxiYWNrLmNvbTo4MDgwL2FwaS9jYWxsYmFjayJ9LHsiY2FsbGJhY2tCb2R5Ijoie1wiYnVja2V0TmFtZVwiOiAkKGJ1Y2tldCksXCJrZXlcIjogJChrZXkpLFwiaGFzaFwiOiAkKGV0YWcpLFwiaWRcIjogJHt4OmlkfSxcImNyZWF0ZXRpbWVcIjogJHt4OnRpbWV9fSJ9LHsieDp0aW1lIjoiMjAxOS0xMi0wNiAxODowMTozNCJ9XX0 -----------------------------7e32de17c166a Content-Disposition: form-data; name="signature" w0nW7iiC4Wfav9SXkU/NiSI99E8= -----------------------------7e32de17c166a Content-Disposition: form-data; name="x-obs-meta-test1" value1 -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackUrl" http://my.callback.com:8080/api/callback -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackBody" {"bucketName": $(bucket),"key": $(key),"hash": $(etag),"id": $(x:id),"createtime": $(x:time)} -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackHost" my.callback.com -----------------------------7e32de17c166a Content-Disposition: form-data; name="callbackBodyType" application/json -----------------------------7e32de17c166a Content-Disposition: form-data; name="x:id" test-example-id -----------------------------7e32de17c166a Content-Disposition: form-data; name="x:time" 2019-12-06 18:01:34 -----------------------------7e32de17c166a Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt" Content-Type: text/plain 123456 ---------------------------7e32de17c166a Content-Disposition: form-data; name="submit" Upload -----------------------------7e32de17c166a-- ``` | 其中policy为： ``` { "expiration": "2020-10-01T12:00:00.000Z", "conditions": [ {"bucket": "examplebucket"}, ["eq", "$key", "file/obj1"], {"x-obs-meta-test1":"value1"}, {"callbackUrl":"http://my.callback.com:8080/api/callback"}, {"callbackBody":"{\"bucketName\": $(bucket),\"key\": $(key),\"hash\": $(etag),\"id\": $(x:id),\"createtime\": $(x:time)}"}, {"x:time":"2019-12-06 18:01:34"} ] } ``` policy中包含了callbackUrl、callbackBody、x:time这三个回调参数，会对这三个参数做条件校验，没有包含callbackHost、callbackBodyType、x:id这三个回调参数，不对这三个参数做条件校验。 policy中可以不包含回调参数，也可以包含部分/全部回调参数。 bucket、key、x-obs-meta-test1为必须包含的表单元素。  回调body为： ``` {"bucketName": $(bucket),"key": $(key),"hash": $(etag),"id": $(x:id),"createtime": $(x:time)} ``` 其中系统变量bucket=examplebucket，key=file/obj1，etag=f447b20a7fcbf53a5d5be013ea0b15af，自定义变量x:id=test-example-id，x:time=2019-12-06 18:01:34。 最终回调的json消息体是： ``` {"bucketName": "examplebucket","key": "file/obj1","hash": "f447b20a7fcbf53a5d5be013ea0b15af","id": "test-example-id","createtime": "2019-12-06 18:01:34"} ``` |
   
#### PUT上传及合并段回调
PUT上传对象以及合并段API中，使用回调时，与POST上传对象使用回调主要有以下几点不同：
1. 回调参数是通过头域x-obs-callback或者请求参数x-obs-callback携带，**携带的回调策略必须是经过BASE64编码的JSON字符串** ，否则OBS将返回400，Invalid Base64 encoding，对象上传失败。该JSON字符串中能够携带的回调参数同[表1]，回调body体支持的系统变量同[表3]。
2. callbackUrl未配置或者配置为空时，视为未配置回调策略，对象仍正常上传，不执行回调。
3. 不支持自定义变量。
 
#### PUT上传回调请求消息样式
PUT上传对象以及合并段API中，回调参数可以通过头域x-obs-callback或者请求参数x-obs-callback携带，二者建议选择其一。如果**二者共存，只有头域x-obs-callback携带的回调参数生效。**
**通过请求参数x-obs-callback携带：**
```
PUT /example.txt?x-obs-callback=xxx HTTP/1.1
User-Agent: curl/7.29.0
Host: examplebucket.obs.cn-north-4.myhuaweicloud.com
Accept: */*
Date: Wed, 14 Oct 2020 04:11:15 GMT
Authorization: OBS H4IPJX0TQTHTHEBQQCEC:gYqplLq30dEX7GMi2qFWyjdFsyw=
Content-Length: 1024
Expect: 100-continue
[1024 Byte data content]
```
**通过头域x-obs-callback携带：**
```
PUT /example.txt? HTTP/1.1
User-Agent: curl/7.29.0
Host: examplebucket.obs.cn-north-4.myhuaweicloud.com
Accept: */*
Date: Wed, 14 Oct 2020 04:11:15 GMT
Authorization: OBS H4IPJX0TQTHTHEBQQCEC:gYqplLq30dEX7GMi2qFWyjdFsyw=
x-obs-callback: xxx
Content-Length: 1024
Expect: 100-continue
[1024 Byte data content]
```
![](https://support.huaweicloud.com/api-obs/public_sys-resources/notice_3.0-zh-cn.png)
OBS在计算CanonicalizedHeaders和CanonicalizedResource时，会分别将头域x-obs-callback以及请求参数x-obs-callback纳入签名计算的范围，参考[OBS签名机制概述](https://support.huaweicloud.com/api-obs/obs_04_0009.html)。
#### 响应消息样式
```
HTTP/1.1 status_code
Content-Type: type
Server: OBS
Date: date
x-obs-request-id: request-id 
Content-Length: length
ETag: etag
```
![](https://support.huaweicloud.com/api-obs/public_sys-resources/notice_3.0-zh-cn.png)
在合并段API中，不使用回调功能时，响应消息body体中为合并段的结果（XML格式），参考[合并段-CompleteMultipartUpload](https://support.huaweicloud.com/api-obs/obs_04_0102.html)，当使用回调功能时，响应消息body体中为回调服务器返回的响应消息body体的内容，例如{"status":"success"}
#### PUT上传对象、合并段JSON回调策略示例
**示例1：**
```
{
"callbackUrl":"http://www.example.com/callback",
"callbackBody": "{\"bucket\":\"$(bucket)\",\"key\":\"$(key)\",\"override\":\"$(override)\"}",
"callbackBodyType":"application/json"
}
```
**示例2：**
```
{
"callbackUrl":"http://www.example.com/callback1;http://www.example.com/callback2",
"callbackBody":"bucket=$(bucket)&key=$(key)&override=$(override)"
}
```
#### PUT上传对象、合并段回调示例
下面的几张表提供了一些回调请求的示例：
表8在PUT上传对象API中，通过请求参数x-obs-callback携带回调策略 
| 请求                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
|:---|:---|
| ``` PUT /example.txt?x-obs-callback=eyJjYWxsYmFja0JvZHkiOiAie1wib2JqZWN0TmFtZVwiOiBcIiQoa2V5KVwiLCBcImJ1Y2tldFwiOiBcIiQoYnVja2V0KVwiLCBcImV4dFwiOiBcIiQoZXh0KVwiLCBcImV0YWdcIjogXCIkKGV0YWcpXCIsIFwib3ZlcnJpZGVcIjogXCIkKG92ZXJyaWRlKVwiLCBcInNpemVcIjogXCIkKHNpemUpXCJ9IiwgImNhbGxiYWNrVXJsIjogImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2sifQ== HTTP/1.1 User-Agent: curl/7.29.0 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Accept: */* Date: Wed, 14 Oct 2020 04:11:15 GMT Authorization: OBS H4IPJX0TQTHTHEBQQCEC:gYqplLq30dEX7GMi2qFWyjdFsyw= Content-Length: 1024 Expect: 100-continue [1024 Byte data content] ``` | 其中回调策略JSON字符串为： ``` {"callbackBody": "{\"objectName\": \"$(key)\", \"bucket\": \"$(bucket)\", \"ext\": \"$(ext)\", \"etag\": \"$(etag)\", \"override\": \"$(override)\", \"size\": \"$(size)\"}", "callbackUrl": "http://www.example.com/callback"} ```  在回调策略中包含了callbackUrl和callbackBody两个回调参数，该回调策略JSON字符串经过BASE64编码之后即为：eyJjYWxsYmFja0JvZHkiOiAie1wib2JqZWN0TmFtZVwiOiBcIiQoa2V5KVwiLCBcImJ1Y2tldFwiOiBcIiQoYnVja2V0KVwiLCBcImV4dFwiOiBcIiQoZXh0KVwiLCBcImV0YWdcIjogXCIkKGV0YWcpXCIsIFwib3ZlcnJpZGVcIjogXCIkKG92ZXJyaWRlKVwiLCBcInNpemVcIjogXCIkKHNpemUpXCJ9IiwgImNhbGxiYWNrVXJsIjogImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2FsbGJhY2sifQ== 最后通过请求参数x-obs-callback携带。  如果该桶中不存在对象名为example.txt的对象，则最终回调消息体是： ``` {"objectName":"example.txt","bucket":"examplebucket","ext":"txt","etag":"f447b20a7fcbf53a5d5be013ea0b15af","override":"false","size":"1024"} ``` |
   
表9在PUT上传对象API中，通过头域x-obs-callback携带回调策略 
| 请求                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
|:---|:---|
| ``` PUT /example.txt? HTTP/1.1 User-Agent: curl/7.29.0 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Accept: */* Date: Wed, 14 Oct 2020 04:11:15 GMT Authorization: OBS H4IPJX0TQTHTHEBQQCEC:gYqplLq30dEX7GMi2qFWyjdFsyw= x-obs-callback: eyJjYWxsYmFja0JvZHkiOiAia2V5PSQoa2V5KSZvdmVycmlkZT0kKG92ZXJyaWRlKSIsICJjYWxsYmFja1VybCI6ICJodHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhbGxiYWNrMTtodHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhbGxiYWNrMiJ9 Content-Length: 1024 Expect: 100-continue [1024 Byte data content] ``` | 其中回调策略JSON字符串为： ``` {"callbackBody": "key=$(key)&override=$(override)", "callbackUrl": "http://www.example.com/callback1;http://www.example.com/callback2"} ```  在回调策略中包含了callbackUrl和callbackBody两个回调参数，该回调策略JSON字符串经过BASE64编码之后即为：eyJjYWxsYmFja0JvZHkiOiAia2V5PSQoa2V5KSZvdmVycmlkZT0kKG92ZXJyaWRlKSIsICJjYWxsYmFja1VybCI6ICJodHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhbGxiYWNrMTtodHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhbGxiYWNrMiJ9 最后通过头域x-obs-callback携带。  如果example.txt对象名在该桶中已经存在，那么最终回调消息体为： ``` key=example.txt&override=true ``` |
   
表10在合并段API中，通过头域x-obs-callback携带回调策略 
| 请求                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
|:---|:---|
| ``` POST /example.txt?uploadId=00000163D46218698DF407362295674C HTTP/1.1 User-Agent: curl/7.29.0 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Accept: */* Date: Wed, 14 Oct 2020 04:11:15 GMT Authorization: OBS H4IPJX0TQTHTHEBQQCEC:dOfK9iILcKxo58tRp3fWeDoYzKA= x-obs-callback: eyJjYWxsYmFja0JvZHkiOiAie1wiaGFzaFwiOiBcIiQoZXRhZylcIiwgXCJrZXlcIjogXCIkKGtleSlcIn0iLCAiY2FsbGJhY2tVcmwiOiAiaHR0cDovL3d3dy5leGFtcGxlLmNvbS9jYWxsYmFjayJ9 Content-Length: 422 <?xml version="1.0" encoding="utf-8"?> <CompleteMultipartUpload> <Part> <PartNumber>1</PartNumber> <ETag>a54357aff0632cce46d942af68356b38</ETag> </Part> <Part> <PartNumber>2</PartNumber> <ETag>0c78aef83f66abc1fa1e8477f296d394</ETag> </Part> <Part> <PartNumber>3</PartNumber> <ETag>acbd18db4cc2f85cedef654fccc4a4d8</ETag> </Part> </CompleteMultipartUpload> ``` | 其中回调策略JSON字符串为： ``` {"callbackBody": "{\"hash\": \"$(etag)\", \"key\": \"$(key)\"}", "callbackUrl": "http://www.example.com/callback"} ```  在回调策略中包含了callbackUrl和callbackBody两个回调参数，该回调策略JSON字符串经过BASE64编码之后即为： eyJjYWxsYmFja0JvZHkiOiAie1wiaGFzaFwiOiBcIiQoZXRhZylcIiwgXCJrZXlcIjogXCIkKGtleSlcIn0iLCAiY2FsbGJhY2tVcmwiOiAiaHR0cDovL3d3dy5leGFtcGxlLmNvbS9jYWxsYmFjayJ9 最后通过头域x-obs-callback携带。  最终回调消息体为: ``` {"hash":"aa2a0304e377796ad5f9793f237f22a1-3","key":"example.txt"} ``` |
   
表11在合并段API中，通过请求参数x-obs-callback携带回调策略 
| 请求                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
|:---|:---|
| ``` POST /example.txt?uploadId=00000163D46218698DF407362295674C&x-obs-callback=eyJjYWxsYmFja0JvZHkiOiAib3ZlcnJpZGU9JChvdmVycmlkZSkmZnNpemU9JChmc2l6ZSkiLCAiY2FsbGJhY2tVcmwiOiAiaHR0cDovL3d3dy5leGFtcGxlLmNvbS9jYWxsYmFjazE7aHR0cDovL3d3dy5leGFtcGxlLmNvbS9jYWxsYmFjMjtodHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhbGxiYWNrMyJ9 HTTP/1.1 User-Agent: curl/7.29.0 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Accept: */* Date: Wed, 14 Oct 2020 04:11:15 GMT Authorization: OBS H4IPJX0TQTHTHEBQQCEC:dOfK9iILcKxo58tRp3fWeDoYzKA= Content-Length: 422 <?xml version="1.0" encoding="utf-8"?> <CompleteMultipartUpload> <Part> <PartNumber>1</PartNumber> <ETag>a54357aff0632cce46d942af68356b38</ETag> </Part> <Part> <PartNumber>2</PartNumber> <ETag>0c78aef83f66abc1fa1e8477f296d394</ETag> </Part> <Part> <PartNumber>3</PartNumber> <ETag>acbd18db4cc2f85cedef654fccc4a4d8</ETag> </Part> </CompleteMultipartUpload> ``` | 其中回调策略JSON字符串为： ``` {"callbackBody": "override=$(override)&fsize=$(fsize)", "callbackUrl": "http://www.example.com/callback1;http://www.example.com/callback2;http://www.example.com/callback3"} ```  在回调策略中包含了callbackUrl和callbackBody两个回调参数，callbackUrl指定了3个，callbackBody中使用了系统变量$(override)以及$(fsize)。该回调策略JSON字符串经过BASE64编码之后即为： eyJjYWxsYmFja0JvZHkiOiAib3ZlcnJpZGU9JChvdmVycmlkZSkmZnNpemU9JChmc2l6ZSkiLCAiY2FsbGJhY2tVcmwiOiAiaHR0cDovL3d3dy5leGFtcGxlLmNvbS9jYWxsYmFjazE7aHR0cDovL3d3dy5leGFtcGxlLmNvbS9jYWxsYmFjMjtodHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhbGxiYWNrMyJ9 最后通过请求参数x-obs-callback携带。  如果该桶中已经存在名为example.txt的对象，那么最终回调消息体为： ``` override=true&fsize=104858 ``` |
   
#### 返回码
带回调参数的POST上传对象的返回码与普通POST上传对象不同。普通POST上传对象HTTP状态码是"204 No Content"。带回调参数的POST上传对象、PUT上传对象以及合并段返回结果是回调结果，如果回调成功，一般会返回"200 OK"，如果回调失败，会返回203。
表12回调请求返回码 
| HTTP状态码                           | 说明             |
|:---|:---|
| 200 OK                            | 上传对象成功，并且回调成功。 |
| 203 Non Authoritative Information | 上传对象成功，但是回调失败。 |
   
#### SDK示例代码
以下为SDK回调示例代码：
| [Java](https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0613.html) | [Go](https://support.huaweicloud.com/sdk-go-devg-obs/obs_33_0605.html) | [Android](https://support.huaweicloud.com/sdk-android-devg-obs/obs_26_0413.html) | [iOS](https://support.huaweicloud.com/sdk-ios-devg-obs/obs_27_4404.html) |
|---|---|---|---|
   
#### 相关文档
- 了解更多回调相关信息请参考[使用上传回调获取对象信息](https://support.huaweicloud.com/usermanual-obs/obs_41_0079.html)
- 最佳实践：[Web端直传OBS并设置上传回调](https://support.huaweicloud.com/bestpractice-obs/obs_05_2317.html)
- 最佳实践：[使用临时安全凭证直传OBS并设置上传回调](https://support.huaweicloud.com/bestpractice-obs/obs_05_2316.html)
 
