first commit
This commit is contained in:
130
COS_POST_UPLOAD_GUIDE.md
Normal file
130
COS_POST_UPLOAD_GUIDE.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user