You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:07:15