本页面介绍如何在 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.createstorage.objects.delete- 只有覆盖现有对象的上传操作需要此权限。
storage.objects.setRetention- 只有包含对象保留锁定的上传操作才需要此权限。
如需了解如何授予存储桶的角色,请参阅设置和管理存储桶的 IAM 政策。
启动可续传上传会话
如需启动可续传上传会话,请执行以下操作:
JSON API
安装并初始化 gcloud CLI,以便为
Authorization标头生成访问令牌。(可选)创建一个 JSON 文件,其中包含您要在上传的对象上设置的元数据。例如,以下 JSON 文件将您要上传到的对象的
contentType元数据设置为image/png:{ "contentType": "image/png" }使用
cURL,通过POSTObject 请求调用 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状态代码,类似于以下内容:HTTP/2 200 content-type: text/plain; charset=utf-8 x-guploader-uploadid: ABgVH8_jqDHM_KOvNAJCx73r9v5fINktk9U-pXana1szCM5803tlJ7CKsRbDxkyYCrfEiNqzcZ6B7DfoDtc-bdzpH-SpVTAMEO9EQV34qG0-0yk location: https://storage.googleapis.com/upload/storage/v1/b/my-bucket/o?uploadType=resumable&name=cat-pic.jpeg&upload_id=ABgVH8_jqDHM_KOvNAJCx73r9v5fINktk9U-pXana1szCM5803tlJ7CKsRbDxkyYCrfEiNqzcZ6B7DfoDtc-bdzpH-SpVTAMEO9EQV34qG0-0yk date: Mon, 07 Jul 2025 14:57:21 GMT vary: Origin vary: X-Origin cache-control: no-cache, no-store, max-age=0, must-revalidate expires: Mon, 01 Jan 1990 00:00:00 GMT pragma: no-cache content-length: 0 server: UploadServer alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
将响应的
location标头中提供的可续传会话 URI 保存到POSTObject 请求中。上传对象数据的后续请求会用到此 URI。
XML API
安装并初始化 gcloud CLI,以便为
Authorization标头生成访问令牌。使用
cURL,通过正文为空的POSTObject 请求调用 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 保存到POSTObject 请求中。上传对象数据的后续请求会用到此 URI。
上传数据
启动可续传上传后,您可以通过以下两种方法上传对象的数据:
- 在单个区块中:此方法通常具有最佳的效果,因为它需要较少的请求,因此具有更好的性能。
- 在多个区块中:如果您需要减少单个请求中传输的数据量(例如,单个请求有固定时间限制时),或在上传开始时不了解上传操作的总大小。
单个区块上传
如需使用单个数据块上传数据,请执行以下操作:
JSON API
使用
cURL,通过PUTObject 请求调用 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,通过PUTObject 请求调用 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,通过PUTObject 请求调用 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,通过PUTObject 请求(该请求从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,通过PUTObject 请求(该请求从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 批量发送多个请求。