Google Storage可恢复分块上传CORS异常:跨域允许头缺失
问题原因与解决方案
1. 初始POST请求(创建会话)无CORS头的原因
你生成签名URL时,仅指定了x-goog-resumable扩展头,但没有将请求中要发送的Origin头加入签名的扩展头列表。GCS对签名URL的请求有严格要求:所有在请求中携带的自定义头(包括Origin)必须在签名时通过withExtHeaders声明,否则GCS不会返回CORS相关响应头。
修复代码
修改签名URL生成逻辑,将Origin头加入withExtHeaders:
val signedUrl = storage .signUrl( BlobInfo.newBuilder(BlobId.of(contentType.bucket, objectName)).build(), 15, TimeUnit.MINUTES, Storage.SignUrlOption.httpMethod(HttpMethod.POST), Storage.SignUrlOption.withExtHeaders( mapOf( "x-goog-resumable" to "start", "Origin" to origin // 加入请求要发送的Origin值 ), ), Storage.SignUrlOption.signWith(storageUploadCredentials), Storage.SignUrlOption.withV4Signature(), ) .toString()
如果你的Origin是动态多域名,可以将Origin的签名值设为*,同时配合桶的CORS配置允许对应域名,不过需确认SDK版本支持通配符头的签名规则。
2. 后续PUT请求(上传块)无CORS头的原因
初始POST响应返回的location是GCS生成的会话URL,这个URL的CORS处理完全依赖桶的CORS配置,而非签名URL规则。你需要确保桶的CORS配置允许PUT方法,并且包含你的请求Origin。
示例桶CORS配置(JSON格式)
[ { "origin": ["你的Origin域名"], "method": ["POST", "PUT", "OPTIONS"], "responseHeader": ["Content-Type", "x-goog-resumable", "Access-Control-Allow-Origin"], "maxAgeSeconds": 3600 } ]
必须包含OPTIONS方法以支持浏览器预检请求;responseHeader可直接用"*"允许所有响应头,简化配置。
3. 错误POST请求返回CORS头的原因
向会话URL发送POST请求时,GCS返回405(方法不允许),此时GCS会优先触发CORS逻辑——错误响应场景下,GCS会自动根据桶的CORS配置返回对应头;而正确请求(初始POST创建会话、PUT上传块)因签名URL未包含Origin头(初始POST)或桶CORS配置不匹配(PUT),所以未返回CORS头。
内容的提问来源于stack exchange,提问作者Vojtěch
相关产品推荐
相关产品推荐

