Files
1818web-hoduan/COS_POST_UPLOAD_GUIDE.md

131 lines
3.6 KiB
Markdown
Raw Permalink Normal View History

2026-02-13 18:18:20 +08:00
# COS POST 表单上传指南
## 问题说明
如果出现 403 错误,通常是因为前端提交的表单字段名不符合 COS 要求。
---
## ✅ 正确的前端上传代码
### 方式1使用 COS 标准字段(推荐)
```javascript
// 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 的字段名
```javascript
// 如果前端代码还在用 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` 开头:
```javascript
formData.append('key', data.dir + fileName); // ✅ 正确
formData.append('key', fileName); // ❌ 错误
```
### 3. CORS 错误
**原因:** COS 存储桶未配置跨域规则
**解决:** 在腾讯云 COS 控制台配置 CORS见主文档
---
## 🧪 测试上传
使用以下 curl 命令测试:
```bash
# 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"
```
---
## 📚 参考文档
- [腾讯云 COS POST 表单上传](https://cloud.tencent.com/document/product/436/14690)
- [COS 签名算法](https://cloud.tencent.com/document/product/436/7778)