Files
1818web-hoduan/COS_POST_UPLOAD_GUIDE.md
Claude Workbench e3e6f1f29d first commit
2026-02-13 18:18:20 +08:00

3.6 KiB
Raw Permalink Blame History

COS POST 表单上传指南

问题说明

如果出现 403 错误,通常是因为前端提交的表单字段名不符合 COS 要求。


正确的前端上传代码

方式1使用 COS 标准字段(推荐)

// 1. 获取签名
const response = await fetch('/user/oss/post-signature', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    userId: '123',
    fileName: 'avatar.jpg'
  })
});

const signData = await response.json();
const data = signData.data;

// 2. 构造表单数据COS 标准字段)
const formData = new FormData();
formData.append('key', data.dir + 'your-file-name.jpg');  // 文件路径
formData.append('policy', data.policy);                    // Policy
formData.append('q-sign-algorithm', 'sha1');               // 签名算法
formData.append('q-ak', data['q-ak']);                     // SecretId
formData.append('q-signature', data['q-signature']);       // 签名
formData.append('file', file);                             // 文件(必须最后)

// 3. 上传到 COS
const uploadResponse = await fetch(data.host, {
  method: 'POST',
  body: formData
});

if (uploadResponse.ok) {
  const fileUrl = data.host + '/' + data.dir + 'your-file-name.jpg';
  console.log('上传成功:', fileUrl);
}

方式2兼容 OSS 的字段名

// 如果前端代码还在用 OSS 的字段名,可以这样:
const formData = new FormData();
formData.append('key', data.dir + 'your-file-name.jpg');
formData.append('policy', data.policy);
formData.append('OSSAccessKeyId', data.accessKeyId);  // 兼容 OSS
formData.append('signature', data.signature);         // 兼容 OSS
formData.append('file', file);

// 但这种方式可能不被 COS 接受建议使用方式1

📋 后端返回的字段说明

字段名 用途 说明
policy Policy Base64 必须
q-sign-algorithm 签名算法 固定为 "sha1"
q-ak SecretId COS 密钥 ID
q-signature 签名 HMAC-SHA1 签名
host 上传地址 COS 存储桶域名
dir 文件目录 文件存储路径前缀

⚠️ 常见错误

1. 403 Forbidden - 签名错误

原因: 表单字段名不对或缺少必要字段

解决: 确保使用 COS 标准字段名:

  • q-ak(不是 accessKeyIdOSSAccessKeyId
  • q-signature(不是 signature
  • q-sign-algorithm

2. 403 Forbidden - Key 不匹配

原因: key 字段的值不符合 Policy 中的前缀限制

解决: 确保 keydata.dir 开头:

formData.append('key', data.dir + fileName);  // ✅ 正确
formData.append('key', fileName);             // ❌ 错误

3. CORS 错误

原因: COS 存储桶未配置跨域规则

解决: 在腾讯云 COS 控制台配置 CORS见主文档


🧪 测试上传

使用以下 curl 命令测试:

# 1. 获取签名
curl -X POST http://localhost:8083/user/oss/post-signature \
  -H "Content-Type: application/json" \
  -d '{"userId":"123","fileName":"test.jpg"}'

# 2. 使用返回的签名上传文件
curl -X POST "https://oss-1818ai-user-img-1302947942.cos.ap-guangzhou.myqcloud.com/" \
  -F "key=user_img/test.jpg" \
  -F "policy=<返回的policy>" \
  -F "q-sign-algorithm=sha1" \
  -F "q-ak=<返回的q-ak>" \
  -F "q-signature=<返回的q-signature>" \
  -F "file=@/path/to/test.jpg"

📚 参考文档