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必填 | string | — | S3 bucket 的 endpoint host(无 https:// 前缀) |
region必填 | string | — | S3 region,如 cn-northwest-1 |
resource_bucket必填 | string | — | 目标 bucket 名 |
resource_uri必填 | string | — | 目标对象 key(含路径前缀) |
sts_ak必填 | string | — | STS access key |
sts_sk必填 | string | — | STS secret key |
session_token必填 | string | — | STS 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));
}常见错误
| 错误 | 原因 | 说明 |
|---|---|---|
AccessDenied | STS 令牌无对应 bucket/key 写权限 | 检查后端 STS 策略;`resource_uri` 是否在策略允许的前缀下 |
ExpiredToken | STS 令牌已过期 | STS 默认有效期 15 分钟到 12 小时;长上传务必预留余量,或上传前重新签 |
NetworkingError | 请求到 endpoint 失败 | 检查 host / Transfer Acceleration 配置;CORS 是否允许浏览器跨源 PUT |
InvalidRequest | host / region / endpoint 不一致 | Transfer Acceleration 模式下 region 必须正确;否则会签名失败 |
下一步
- 默认入口 — 通用工具
- Date — dayjs 包装
- Playground — 工具函数交互测试