向GCS可恢复签名URL发送DELETE请求时持续遭遇CORS错误
问题描述
我尝试用resumable signed url上传文件,存储桶CORS配置如下:
[{"maxAgeSeconds": 3600, "method": ["GET", "PATCH", "DELETE", "OPTIONS", "POST", "PUT"], "origin": ["*"], "responseHeader": ["*"]}]
后端生成签名URL的配置代码:
const options: GetSignedUrlConfig = { version: 'v4', action: 'resumable', expires: Date.now() + 60 * 60 * 1000, // 60分钟 contentType: 'text/plain', };
前端通过axios发送POST初始化会话、PUT上传文件的流程均正常,但上传过程中发送DELETE请求取消上传时(代码如下),先出现Chrome控制台错误:xhr.js?78a4:193 Refused to set unsafe header "content-length",随后触发CORS错误:Access to XMLHttpRequest at 'https://storage.googleapis.com/[bucket]/test/test.mp3? ... &upload_id=ADPycdvPhSounQyXYnfOeyiXu-reeZf2j2ghdrXzHcUkSNzoFmmTa3k8Mutis_hhXJjEiMbP6TtzSbjuXzXSClvHUrqdNUlvCJiy' from origin 'http://localhost:3001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource。期望停止上传却报错,问题出在哪里?
问题根源
- 请求头非法拦截:浏览器会自动管控
Content-Length这类请求头,禁止前端手动设置,你在DELETE请求中添加这个头会被浏览器直接拦截,这是第一个错误的直接原因。 - CORS错误连锁触发:由于浏览器拦截了非法请求头,导致请求未按预期发送到Google Cloud Storage(GCS),或者GCS接收到的请求不符合规范,未返回
Access-Control-Allow-Origin响应头,进而引发CORS报错。
解决方案
直接移除DELETE请求中的Content-Length头即可,修改后的代码:
await axios.delete(resumable_signed_url_session_uri);
额外确认:
- 存储桶CORS配置已包含
DELETE方法,这部分无需调整; - 后端生成签名URL时已设置
action: 'resumable',配置正确。
修改后,浏览器会正常发送DELETE请求到GCS以终止上传会话,GCS也会返回符合CORS要求的响应头,不再触发报错。
内容的提问来源于stack exchange,提问作者jiyoung

