You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scaleway S3兼容对象存储预签名URL分片上传预检请求403问题

问题根因

这是Scaleway对象存储S3兼容层的实现不符合AWS规范导致的:
AWS原生S3处理CORS预检OPTIONS请求时,会完全忽略请求中的签名相关参数,直接根据Bucket的CORS配置返回响应,不会做签名校验。但Scaleway当前的实现会对所有请求(包括OPTIONS预检)都执行签名校验,而你生成的预签名URL是针对PUT方法的,浏览器自动发起的OPTIONS请求方法和签名时的方法不匹配,自然会返回403 AccessDenied错误。你移除查询参数后预检成功,就是因为没有了签名参数,Scaleway的校验逻辑走了纯CORS配置匹配的分支。

可行解决方案

  • 方案1:新增后端代理层
    所有对象存储的跨域请求都先走你自己的后端服务:

    1. 后端收到OPTIONS预检请求时,直接返回符合要求的CORS响应头,不需要转发到Scaleway
    2. 收到实际的PUT分片上传请求时,再把请求转发到Scaleway的预签名地址,或者后端直接用密钥签名后上传
      这个方案兼容性最好,不需要依赖云厂商的修复,也不会额外增加前端复杂度。
  • 方案2:使用表单上传替代预签名PUT上传
    把分片上传的逻辑改成POST表单上传的方式,生成预签名的POST policy,前端用FormData携带分片数据提交,这种方式可以避免触发复杂的预检校验,适配Scaleway的现有实现。

  • 方案3:调整配置尝试兼容(部分场景可用)
    如果你暂时不想加代理,可以尝试做以下调整:

    1. 调整S3客户端初始化配置,强制使用V4版本签名:
    const S3Client = new S3({
      credentials: {
        accessKeyId: env.SCW_ACCESS_KEY,
        secretAccessKey: env.SCW_SECRET_KEY,
      },
      endpoint: `https://s3.${env.SCW_REGION}.scw.cloud`,
      signatureVersion: 'v4', // 强制使用v4版本签名
      region: env.SCW_REGION, // 补充区域参数,签名生成时需要
    })
    
    1. 在Scaleway控制台调整Bucket的CORS规则:精确填写允许的Origin(不要用*通配符)、明确允许OPTIONS和PUT两种方法、允许的请求头明确添加*。
      注意该方案仅在部分Scaleway区域可用,不保证全场景生效。

内容的提问来源于stack exchange,提问作者Antoine Laffargue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:24:04