使用Deno+AWS SDK对接Linode S3兼容存储时上传文件遇阻
PDF上传至对象存储无响应问题排查与解决方案
开发一个简单应用,将单个PDF上传至对象存储,点击提交后请求一直处于缓冲状态无响应。已通过
ListObjectsCommand确认认证、端点和API密钥正常(能返回存储桶对象列表),尝试上传txt文件、移除ContentType属性等操作后仍无法解决。
以下是针对性的排查方向和解决方案:
1. 固定对象键导致的冲突问题
你的代码中使用固定的FILEKEY环境变量作为对象键:
const fileKey = FILEKEY;
如果多次上传复用同一个键,部分对象存储服务会因文件锁定或覆盖操作阻塞请求。解决方法:生成唯一文件键,比如结合时间戳与原文件名:
const fileKey = `${Date.now()}-${file.name}`; // 用时间戳+原文件名保证唯一性
2. 文件读取方式优化
你将File对象转换为Uint8Array上传,可能存在数据读取不完整的情况。建议直接使用文件流作为请求Body:
// 替换原有的fileData转换逻辑 const command = new PutObjectCommand({ Bucket: bucketName, Key: fileKey, Body: file.stream(), // 直接传递文件流 ContentType: file.type, ACL: "public-read", });
3. S3兼容存储的特殊配置
对于非AWS的S3兼容存储(如MinIO、Cloudflare R2等),需添加forcePathStyle配置:
const client = new S3Client({ region: S3_REGION, endpoint: S3_URL, maxAttempts: 3, logger: console, credentials: { accessKeyId: S3_ACCESS_KEY, secretAccessKey: S3_SECRET_KEY, }, forcePathStyle: true, // 开启路径样式,部分兼容存储强制要求 });
4. ACL权限配置排查
ACL: "public-read"需要存储桶允许设置公共读权限,若存储桶策略不允许,可能导致请求挂起而非直接报错。可先移除ACL配置测试:
const command = new PutObjectCommand({ Bucket: bucketName, Key: fileKey, Body: file.stream(), ContentType: file.type, // 暂时注释ACL配置,验证是否能上传成功 });
5. 超时配置与日志排查
当前客户端未设置超时时间,添加超时配置并查看完整日志:
import { NodeHttpHandler } from "@aws-sdk/node-http-handler"; const client = new S3Client({ region: S3_REGION, endpoint: S3_URL, maxAttempts: 3, logger: console, credentials: { accessKeyId: S3_ACCESS_KEY, secretAccessKey: S3_SECRET_KEY, }, requestHandler: new NodeHttpHandler({ connectionTimeout: 30000, // 30秒连接超时 socketTimeout: 30000, // 30秒Socket超时 }), });
同时检查Deno控制台,确认Uploading file to S3...日志后是否有隐藏错误输出。
6. 前端表单提交验证
尝试用自定义Fetch逻辑提交表单,排查前端是否存在请求阻塞问题:
// 在UploadPage组件中添加自定义提交逻辑 export default function UploadPage() { const handleSubmit = async (e) => { e.preventDefault(); const formData = new FormData(e.target); try { const res = await fetch('/', { method: 'POST', body: formData, }); console.log(await res.text()); } catch (err) { console.error(err); } }; return ( <div className="bg-black flex flex-col items-center"> <h1 className="m-5 font-bold text-lg text-white">Upload PDF</h1> <form onSubmit={handleSubmit} encType="multipart/form-data" className="bg-black flex flex-col items-center" > {/* 原有表单内容保持不变 */} </form> </div> ); }
内容的提问来源于stack exchange,提问作者Miguel
相关产品推荐
相关产品推荐

