Skip to content

Resource(/resource 入口)

ts
import { partUpload, upload } from '@tripo3d/utils/resource';

/resource 子入口提供 S3 上传封装,基于 @aws-sdk/client-s3 + @aws-sdk/lib-storage两个函数都需要业务后端先签发临时 STS 令牌——SDK 不内置鉴权流程,只负责把 blob 推到 S3。

临时令牌结构

业务后端签发的 TemporaryToken 必须包含以下字段:

名称 类型 默认值 说明
host必填stringS3 bucket 的 endpoint host(无 https:// 前缀)
region必填stringS3 region,如 cn-northwest-1
resource_bucket必填string目标 bucket 名
resource_uri必填string目标对象 key(含路径前缀)
sts_ak必填stringSTS access key
sts_sk必填stringSTS secret key
session_token必填stringSTS session token
useAccelerateEndpoint必填boolean是否启用 S3 Transfer Acceleration。开启后会忽略 host,自动走 *.s3-accelerate.amazonaws.com

upload

最简上传——单次 Upload 调用,内部按 10MB 分片但不暴露进度回调。

函数签名说明
upload(token: TemporaryToken, blob: Blob) => Promise<{ bucket, key }>上传 Blob 到 S3。完成后返回 bucket+key,异常会 reject
ts
import { upload } from '@tripo3d/utils/resource';

const token = await fetchSTSFromBackend();   // 业务后端签发
const result = await upload(token, file);
console.log(result);                          // { bucket: '...', key: '...' }

partUpload

带进度回调的分片上传——同样 10MB 分片,但禁用 SDK 自动校验和(requestChecksumCalculation: 'WHEN_REQUIRED'),适合上游不支持 checksum 的 S3 兼容存储。

函数签名说明
partUpload(token: TemporaryToken, blob: Blob, onProgress?: (percent) => void) => Promise<{ bucket, key }>分片上传。onProgress 接收 0-100 百分比
ts
import { partUpload } from '@tripo3d/utils/resource';

await partUpload(token, file, (percent) => {
  console.log(`已上传 ${percent.toFixed(1)}%`);
  progressBar.value = percent;
});

upload vs partUpload 选哪个

场景
文件小(< 10MB)、不需要进度upload
文件大、UI 要显示进度条partUpload
S3 兼容存储拒绝 checksum 头partUpload(自动禁用 checksum)

S3 Transfer Acceleration

useAccelerateEndpoint: true 时,SDK 会忽略 host 字段,自动跳到 <bucket>.s3-accelerate.amazonaws.com该 bucket 必须在 AWS 控制台开启 Transfer Acceleration,否则上传会失败。

配套后端接口

业务后端签发临时 STS 通常通过这样的接口:

ts
// POST /api/storage/sts
// Response:
interface TemporaryToken {
  bucket: string;
  expires_at: number;          // 业务字段,SDK 不读
  host: string;
  region: string;
  resource_bucket: string;
  resource_uri: string;
  session_token: string;
  sts_ak: string;
  sts_sk: string;
  useAccelerateEndpoint: boolean;
}

// 前端
async function uploadFile(file: File) {
  const token = await fetch('/api/storage/sts', {
    method: 'POST',
    body: JSON.stringify({ filename: file.name, size: file.size }),
  }).then(r => r.json());

  return partUpload(token, file, (p) => updateProgress(p));
}

常见错误

错误原因说明
AccessDeniedSTS 令牌无对应 bucket/key 写权限检查后端 STS 策略;`resource_uri` 是否在策略允许的前缀下
ExpiredTokenSTS 令牌已过期STS 默认有效期 15 分钟到 12 小时;长上传务必预留余量,或上传前重新签
NetworkingError请求到 endpoint 失败检查 host / Transfer Acceleration 配置;CORS 是否允许浏览器跨源 PUT
InvalidRequesthost / region / endpoint 不一致Transfer Acceleration 模式下 region 必须正确;否则会签名失败

下一步

基于 MIT 协议发布(内部使用)