Files
1818web-hoduan/docs/admin-oss-upload-bug-fix-detail.md
2025-11-14 17:41:15 +08:00

228 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 管理端OSS上传字段名Bug修复详解
## 🐛 问题详细分析
### 错误现象
```xml
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Key>user_img/covers/82D78B6D-B229-0C7B-2567-C023C0386A0A.png</Key>
</Error>
```
### 问题根源
虽然后端成功生成了OSS签名但前端上传时使用了错误的FormData字段名导致文件实际上没有上传到OSS。
---
## 🔍 字段名对照表
### ❌ 错误的字段名(我们文档中的错误示例)
```javascript
// 错误示例 - 不要使用这些字段名
formData.append('OSSAccessKeyId', signature.accessKeyId); // ❌ 错误
formData.append('signature', signature.signature); // ❌ 错误
formData.append('x-oss-signature-version', signature.version); // ❌ 错误
```
### ✅ 正确的字段名OSS POST 签名 V4 要求)
```javascript
// 正确示例 - 必须使用这些字段名
formData.append('key', objectKey); // ✅ 文件路径
formData.append('policy', signature.policy); // ✅ 策略
formData.append('x-oss-credential', signature.x_oss_credential); // ✅ 凭证
formData.append('x-oss-date', signature.x_oss_date); // ✅ 日期
formData.append('x-oss-signature-version', signature.x_oss_signature_version); // ✅ 版本
formData.append('x-oss-signature', signature.x_oss_signature); // ✅ 签名
formData.append('success_action_status', '200'); // ✅ 成功状态
formData.append('file', file); // ✅ 文件
```
---
## 🔧 修复内容
### 1. 修正后端返回字段名
**文件**: `AdminOssServiceImpl.java`
```java
// 修复前
response.put("version", "OSS4-HMAC-SHA256");
response.put("signature", signature);
// 修复后
response.put("x_oss_signature_version", "OSS4-HMAC-SHA256");
response.put("x_oss_signature", signature);
```
### 2. 创建测试页面
**文件**: `test_admin_oss_upload.html`
功能特性:
- 🔐 管理员Token验证
- 📁 多种上传目录选择
- 🔄 新版/兼容接口切换
- 📊 实时上传进度
- 🐛 详细调试信息
- ✅ 文件访问测试
### 3. 修正文档示例
更新所有文档中的前端上传代码示例。
---
## 🚀 正确的上传流程
### 步骤1: 获取上传签名
```javascript
const response = await fetch('/admin/oss/post-signature', {
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fileName: file.name,
directory: 'covers',
maxSizeMB: 50
})
});
const result = await response.json();
const signature = result.data;
```
### 步骤2: 构建FormData关键步骤
```javascript
const formData = new FormData();
// 生成唯一文件名避免冲突
const uniqueFileName = `${Date.now()}_${Math.random().toString(36).substring(2)}_${file.name}`;
const objectKey = `${signature.dir}${uniqueFileName}`;
// 按OSS要求添加字段 - 字段名必须准确!
formData.append('key', objectKey);
formData.append('policy', signature.policy);
formData.append('x-oss-credential', signature.x_oss_credential);
formData.append('x-oss-date', signature.x_oss_date);
formData.append('x-oss-signature-version', signature.x_oss_signature_version);
formData.append('x-oss-signature', signature.x_oss_signature);
formData.append('success_action_status', '200');
formData.append('file', file);
```
### 步骤3: 上传到OSS
```javascript
const uploadResponse = await fetch(signature.host, {
method: 'POST',
body: formData
});
if (uploadResponse.ok) {
const fileUrl = `${signature.host}/${objectKey}`;
console.log('上传成功:', fileUrl);
}
```
---
## 🧪 测试验证
### 使用测试页面
1. 访问 `/test_admin_oss_upload.html`
2. 输入管理员Token
3. 选择文件和目录
4. 点击"生成上传签名"
5. 点击"上传文件到OSS"
6. 点击"测试文件访问"
### 预期结果
- ✅ 签名生成成功
- ✅ 文件上传到OSS成功
- ✅ 文件URL可正常访问
- ✅ 不再出现`NoSuchKey`错误
---
## 🛡️ 常见问题排查
### 问题1: 仍然提示NoSuchKey
**可能原因**:
- 前端仍在使用错误的字段名
- 文件名包含特殊字符
- OSS权限配置问题
**解决方案**:
```javascript
// 检查FormData字段名是否正确
console.log('FormData字段:');
for (let pair of formData.entries()) {
console.log(pair[0], ':', pair[1]);
}
```
### 问题2: 签名生成失败
**可能原因**:
- Token无效或过期
- 权限不足
- 文件类型不支持
**解决方案**:
```javascript
// 检查Token和权限
const token = localStorage.getItem('adminToken');
console.log('当前Token:', token);
```
### 问题3: 上传进度卡住
**可能原因**:
- 网络连接问题
- 文件过大
- OSS服务异常
**解决方案**:
```javascript
// 添加超时处理
const controller = new AbortController();
setTimeout(() => controller.abort(), 60000); // 60秒超时
fetch(signature.host, {
method: 'POST',
body: formData,
signal: controller.signal
});
```
---
## 📚 相关文档更新
以下文档已同步更新正确的字段名:
- ✅ [API文档](./admin-oss-upload-api.md)
- ✅ [使用示例](./admin-oss-upload-examples.md)
- ✅ [功能总览](./admin-oss-upload-readme.md)
---
## 🎯 总结
### ✅ 修复效果
1. **字段名正确**: 使用OSS规范的字段名
2. **上传成功**: 文件能正确上传到OSS
3. **访问正常**: 上传后的文件URL可正常访问
4. **测试工具**: 提供完整的测试页面
### 🚨 重要提醒
1. **字段名必须准确**: OSS对字段名大小写敏感
2. **文件名唯一**: 建议使用时间戳+随机数避免覆盖
3. **错误处理**: 做好网络异常和上传失败的处理
4. **调试信息**: 使用测试页面查看详细的调试信息
---
**修复状态**: ✅ 已完成
**测试状态**: ✅ 已验证
**文档状态**: ✅ 已同步
**风险等级**: 低(不影响现有功能)