3.6 KiB
3.6 KiB
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(不是accessKeyId或OSSAccessKeyId) - ✅
q-signature(不是signature) - ✅
q-sign-algorithm
2. 403 Forbidden - Key 不匹配
原因: key 字段的值不符合 Policy 中的前缀限制
解决: 确保 key 以 data.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"