本页面介绍如何在 Cloud Storage JSON 和 XML API 中发出可续传上传请求。当数据流因通信故障而中断后,您可以利用此协议恢复上传操作。
如需了解如何在 Google Cloud CLI 和客户端库中使用可续传上传,请参阅工具和 API 如何使用可续传上传。
所需的角色
如需获得执行可续传上传所需的权限,请让您的管理员为您授予以下角色之一:
对于包含对象保留锁定的上传,请让您的管理员为您授予存储桶的 Storage Object Admin (
roles/storage.objectAdmin
) IAM 角色。对于其他所有情况,请让您的管理员为您授予存储桶的 Storage Object User (
roles/storage.objectUser
) IAM 角色。
这些预定义角色包含针对其各自的情况将对象上传到存储桶所需的权限。如需查看所需的确切权限,请展开所需权限部分:
所需权限
storage.objects.create
storage.objects.delete
- 只有覆盖现有对象的上传操作需要此权限。
storage.objects.setRetention
- 只有包含对象保留锁定的上传操作才需要此权限。
如需了解如何授予存储桶的角色,请参阅将 IAM 与存储桶搭配使用。
启动可续传上传会话
如需启动可续传上传会话,请执行以下操作:
JSON API
安装并初始化 gcloud CLI,以便为
Authorization
标头生成访问令牌。(可选)创建一个 JSON 文件,其中包含您要在上传的对象上设置的 元数据。例如,以下 JSON 文件将您要上传到的对象的
contentType
元数据设置为image/png
:{ "contentType": "image/png" }
使用
cURL
,通过POST
Object 请求调用 JSON API:curl -i -X POST --data-binary @METADATA_LOCATION \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ -H "Content-Length: INITIAL_REQUEST_LENGTH" \ "https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME"
其中:
METADATA_LOCATION
是 JSON 文件的本地路径,其中包含您在上一步中指定的可选元数据。如果您不添加元数据文件,请排除此文件以及--data-binary @
和Content-Type
标头。INITIAL_REQUEST_LENGTH
是此初始请求正文中的字节数,例如79
。BUCKET_NAME
是对象要上传到的存储桶的名称。例如my-bucket
。OBJECT_NAME
是您要为对象指定的网址编码名称。例如,pets/dog.png
的网址编码为pets%2Fdog.png
。如果您在第 2 步的对象元数据文件中添加了name
,则不需要此名称。
如果您启用了跨域资源共享,则还应在此上传请求和后续上传请求中添加
Origin
标头。您可以向请求添加的可选标头包括
X-Upload-Content-Type
和X-Upload-Content-Length
。如果成功,响应将包含
200
状态代码。将响应的
Location
标头中提供的可续传会话 URI 保存到POST
Object 请求中。上传对象数据的后续请求会用到此 URI。
XML API
安装并初始化 gcloud CLI,以便为
Authorization
标头生成访问令牌。使用
cURL
,通过正文为空的POST
Object 请求调用 XML API:curl -i -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Length: 0" \ -H "Content-Type: OBJECT_CONTENT_TYPE" \ -H "x-goog-resumable: start" \ "https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME"
其中:
OBJECT_CONTENT_TYPE
是该对象的内容类型,例如image/png
。如果您不指定内容类型,Cloud Storage 系统会将对象的Content-Type
元数据设置为application/octet-stream
。BUCKET_NAME
是对象要上传到的存储桶的名称。例如my-bucket
。OBJECT_NAME
是您要为对象指定的网址编码名称。例如,pets/dog.png
的网址编码为pets%2Fdog.png
。
如果您启用了跨域资源共享,则还应在此上传请求和后续上传请求中添加
Origin
标头。如果成功,响应将包含
201
状态消息。将响应的
Location
标头中提供的可续传会话 URI 保存到POST
Object 请求中。上传对象数据的后续请求会用到此 URI。
上传数据
启动可续传上传后,您可以通过以下两种方法上传对象的数据:
- 在单个区块中:此方法通常具有最佳的效果,因为它需要较少的请求,因此具有更好的性能。
- 在多个区块中:如果您需要减少单个请求中传输的数据量(例如,单个请求有固定时间限制时),或在上传开始时不了解上传操作的总大小。
单个区块上传
如需使用单个数据块上传数据,请执行以下操作:
JSON API
使用
cURL
,通过PUT
Object 请求调用 JSON API:curl -i -X PUT --data-binary @OBJECT_LOCATION \ -H "Content-Length: OBJECT_SIZE" \ "SESSION_URI"
其中:
OBJECT_LOCATION
是对象的本地路径。例如Desktop/dog.png
。OBJECT_SIZE
是对象中的字节数。例如20000000
。SESSION_URI
是您在启动可续传上传时Location
标头中返回的值。
或者,您可以添加前缀为
X-Goog-Meta-
的标头,以将对象的自定义元数据添加到此请求中。
XML API
如果上传全部完成,您会收到 200 OK
或 201 Created
响应,以及与资源相关联的任何元数据。
如果上传请求中断或者您收到 5xx
响应,请按照恢复中断的上传中的步骤操作。
多个数据块上传
如需使用多个数据块上传数据,请执行以下操作:
JSON API
根据您要上传的整体数据创建数据块。
数据块的大小应该是 256 KiB(256 x 1024 字节)的整数倍,除非数据块是结束上传的最后一个数据块。较大的数据块大小通常可使上传速度更快,但请注意,速度和内存用量之间存在权衡。我们建议您使用至少 8 MiB 作为数据块大小。
使用
cURL
,通过PUT
Object 请求调用 JSON API:curl -i -X PUT --data-binary @CHUNK_LOCATION \ -H "Content-Length: CHUNK_SIZE" \ -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \ "SESSION_URI"
其中:
CHUNK_LOCATION
是您当前正在上传的数据块的本地路径。CHUNK_SIZE
是您正在当前请求中上传的字节数。例如8388608
。CHUNK_FIRST_BYTE
是您正在上传的数据块包含的整个对象中的起始字节。CHUNK_LAST_BYTE
是您正在上传的数据块包含的整个对象中的结束字节。TOTAL_OBJECT_SIZE
是您正在上传的对象的总大小。SESSION_URI
是您在启动可续传上传时Location
标头中返回的值。
Content-Range
的一个示例为Content-Range: bytes 0-8388607/20000000
。如需详细了解此标头,请参阅Content-Range
。如果请求成功,服务器会返回
308 Resume Incomplete
。响应包含Range
标头。对您要上传的每个剩余数据块重复上述步骤,并使用每个响应的
Range
标头中包含的上限值来确定每个连续数据块的开始位置;您不应假定服务器已收到任何给定请求中发送的所有字节。(可选)在可续传上传的最终请求中,您可以添加前缀为
X-Goog-Meta-
的标头,以添加对象的自定义元数据。
XML API
根据您要上传的整体数据创建数据块。
数据块的大小应该是 256 KiB(256 x 1024 字节)的整数倍,除非数据块是结束上传的最后一个数据块。较大的数据块大小通常可使上传速度更快,但请注意,速度和内存用量之间存在权衡。我们建议您使用至少 8 MiB 作为数据块大小。
使用
cURL
,通过PUT
Object 请求调用 XML API:curl -i -X PUT --data-binary @CHUNK_LOCATION \ -H "Content-Length: CHUNK_SIZE" \ -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \ "SESSION_URI"
其中:
CHUNK_LOCATION
是您当前正在上传的数据块的本地路径。CHUNK_SIZE
是您正在当前请求中上传的字节数。例如8388608
。CHUNK_FIRST_BYTE
是您正在上传的数据块包含的整个对象中的起始字节。CHUNK_LAST_BYTE
是您正在上传的数据块包含的整个对象中的结束字节。TOTAL_OBJECT_SIZE
是您正在上传的对象的总大小。SESSION_URI
是您在启动可续传上传时Location
标头中返回的值。
Content-Range
的一个示例为Content-Range: bytes 0-8388607/20000000
。如需详细了解此标头,请参阅Content-Range
。如果请求成功,服务器会返回
308 Resume Incomplete
。响应包含Range
标头。对您要上传的每个剩余数据块重复上述步骤,并使用每个响应的
Range
标头中包含的上限值来确定每个连续数据块的开始位置;您不应假定服务器已收到任何给定请求中发送的所有字节。
上传全部完成后,您会收到 200 OK
或 201 Created
响应,以及与资源相关联的任何元数据。
如有任何分块上传中断或者您收到 5xx
响应,您应完整地重新发送中断的分块,或者从中断的地方继续执行之前中断的上传。
检查可续传上传的状态
如果您的可续传上传中断或者您不确定上传已完成,则可以检查上传的状态:
JSON API
XML API
200 OK
或 201 Created
响应表明上传已完成,无需执行进一步操作。
308 Resume Incomplete
响应表明您需要继续上传数据。
- 如果 Cloud Storage 尚未保留任何字节,则
308
响应没有Range
标头。在这种情况下,您应从头开始上传。 - 否则,
308
响应具有Range
标头,该标头表明 Cloud Storage 目前已保留哪些字节。在恢复中断的上传时,请使用此值。
恢复中断的上传
如果上传请求在收到响应之前被终止,或者您收到 503
或 500
响应,则需要从中断的地方恢复中断的上传。如需恢复中断的上传,请执行以下操作:
JSON API
将响应中包含的
Range
标头的上限值保存到您的状态检查中。如果响应没有Range
标头,则 Cloud Storage 尚未保留任何字节,您应从头开始上传。确保您要上传的对象数据从
Range
标头中的上限值后面的字节开始。如果中断的请求包含前缀为
X-Goog-Meta-
的标头,请在请求中添加这些标头才能继续上传。使用
cURL
,通过PUT
Object 请求(该请求从Range
标头中的值后面的字节开始上传数据)调用 JSON API:curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \ -H "Content-Length: UPLOAD_SIZE_REMAINING" \ -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \ "SESSION_URI"
其中:
PARTIAL_OBJECT_LOCATION
是您要上传的数据剩余部分的本地路径。UPLOAD_SIZE_REMAINING
是您正在当前请求中上传的字节数。例如,如果总大小为 20000000 的对象在上传字节 0-42 后中断,则上传该对象剩余部分时的UPLOAD_SIZE_REMAINING
为19999957
。NEXT_BYTE
是您在第 2 步中保存的值后的下一个整数。例如,如果42
是第 2 步中的上限值,则NEXT_BYTE
的值为43
。LAST_BYTE
是此PUT
请求中包含的结束字节。例如,为了上传完总大小为20000000
的对象,LAST_BYTE
的值为19999999
。TOTAL_OBJECT_SIZE
是您正在上传的对象的总大小。例如20000000
。SESSION_URI
是您在启动可续传上传时Location
标头中返回的值。
XML API
将响应中包含的
Range
标头的上限值保存到您的状态检查中。如果响应没有Range
标头,则 Cloud Storage 尚未保留任何字节,您应从头开始上传。确保您要上传的对象数据从
Range
标头中的上限值后面的字节开始。使用
cURL
,通过PUT
Object 请求(该请求从Range
标头中的值后面的字节开始上传数据)调用 XML API:curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \ -H "Content-Length: UPLOAD_SIZE_REMAINING" \ -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \ "SESSION_URI"
其中:
PARTIAL_OBJECT_LOCATION
是您要上传的数据剩余部分的本地路径。UPLOAD_SIZE_REMAINING
是您正在当前请求中上传的字节数。例如,如果总大小为 20000000 的对象在上传字节 0-42 后中断,则上传该对象剩余部分时的UPLOAD_SIZE_REMAINING
为19999957
。NEXT_BYTE
是您在第 2 步中保存的值后的下一个整数。例如,如果42
是第 2 步中的上限值,则NEXT_BYTE
的值为43
。LAST_BYTE
是此PUT
请求中包含的结束字节。例如,为了上传完总大小为20000000
的对象,LAST_BYTE
的值为19999999
。TOTAL_OBJECT_SIZE
是您正在上传的对象的总大小。例如20000000
。SESSION_URI
是您在启动可续传上传时Location
标头中返回的值。
在会话 URI 处于活跃状态时,您可以根据需要多次恢复上传;会话 URI 的有效期为一周。数据上传成功后,Cloud Storage 会返回 200 OK
或 201 created
状态代码。
取消上传
如需取消未完成的可续传上传并阻止任何进一步操作,请执行以下操作:
JSON API
使用
cURL
,通过DELETE
请求调用 JSON API:curl -i -X DELETE -H "Content-Length: 0" \ "SESSION_URI"
其中:
SESSION_URI
是您在启动可续传上传时Location
标头中返回的值。
如果成功,响应将包含 499
状态代码。进一步尝试查询或恢复上传将导致 4xx
响应。
XML API
使用
cURL
,通过DELETE
请求调用 XML API:curl -i -X DELETE -H "Content-Length: 0" \ "SESSION_URI"
其中:
SESSION_URI
是您在启动可续传上传时Location
标头中返回的值。
如果成功,响应将包含 204
状态代码,未来尝试查询或恢复上传也会导致 204
响应。
失败处理
在极少数情况下,由于存储桶的权限发生了更改,或者对最终上传的对象进行完整性检查时检测到不匹配,因此请求恢复中断的上传可能会失败,并返回不可重试的“4xx”错误。如果发生这种情况,请通过启动新的可续传上传会话重试上传。
后续步骤
- 详细了解可续传上传。
- 阅读 JSON API 和 XML API 概览。
- 流式上传未知大小的对象。
- 向 Cloud Storage JSON API 批量发送多个请求。