Bun 的 S3 API 很快

Response 和 Blob API(如 Bun 的本地文件系统 API)。
- AWS S3
- Cloudflare R2
- DigitalOcean Spaces
- MinIO
- Backblaze B2
- …以及任何其他 S3 兼容的存储服务
基本用法
有几种方法可以与 Bun 的 S3 API 交互。Bun.S3Client & Bun.s3
Bun.s3 等价于 new Bun.S3Client(),依赖环境变量获取凭据。
要显式设置凭据,请将它们传递给 Bun.S3Client 构造函数。
使用 S3 文件
S3Client 中的 file 方法返回对 S3 上文件的惰性引用。
Bun.file(path) 类似,S3Client 的 file 方法是同步的。在调用依赖网络请求的方法之前,它不会发出任何网络请求。
从 S3 读取文件
如果您使用过fetch API,那么您就熟悉 Response 和 Blob API。S3File 扩展了 Blob。适用于 Blob 的相同方法也适用于 S3File。
内存优化
像text()、json()、bytes() 或 arrayBuffer() 这样的方法在可能的情况下避免复制字符串或字节到内存中。
如果文本恰好是 ASCII,Bun 会直接将字符串传输到 JavaScriptCore(引擎)而不进行转码,也不会在内存中复制字符串。当您使用 .bytes() 或 .arrayBuffer() 时,它也会避免在内存中复制字节。
这些辅助方法不仅简化了 API,还使其更快。
向 S3 写入和上传文件
写入 S3 同样简单。处理大文件(流)
Bun 自动处理大文件的多部分上传并提供流功能。适用于本地文件的相同 API 也适用于 S3 文件。预签名 URL
当您的生产服务需要让用户将文件上传到您的服务器时,让用户直接上传到 S3 而不是让您的服务器充当中间人通常更可靠。 为了实现这一点,您可以为 S3 文件预签名 URL。这会生成一个带有签名的 URL,允许用户安全地将该特定文件上传到 S3,而不会暴露您的凭据或授予他们对您的存储桶的不必要访问权限。 默认行为是生成一个 24 小时后过期的GET URL。Bun 尝试从文件扩展名推断内容类型。如果无法推断,它将默认为 application/octet-stream。
设置 ACL
要在预签名 URL 上设置 ACL(访问控制列表),传递acl 选项:
| ACL | 说明 |
|---|---|
"public-read" | 该对象可被公众读取。 |
"private" | 该对象只能由存储桶所有者读取。 |
"public-read-write" | 该对象可被公众读取和写入。 |
"authenticated-read" | 该对象可由存储桶所有者和经过身份验证的用户读取。 |
"aws-exec-read" | 该对象可由发起请求的 AWS 账户读取。 |
"bucket-owner-read" | 该对象可由存储桶所有者读取。 |
"bucket-owner-full-control" | 该对象可由存储桶所有者读取和写入。 |
"log-delivery-write" | 该对象可由用于日志传递的 AWS 服务写入。 |
过期 URL
要为预签名 URL 设置过期时间,传递expiresIn 选项。
method
要为预签名 URL 设置 HTTP 方法,传递 method 选项。
new Response(S3File)
要快速将用户重定向到 S3 文件的预签名 URL,将 S3File 实例作为正文传递给 Response 对象。
这将自动将用户重定向到 S3 文件的预签名 URL,为您节省了将文件下载到服务器再发送回用户的内存、时间和带宽成本。
对 S3 兼容服务的支持
Bun 的 S3 实现适用于任何 S3 兼容的存储服务。只需指定适当的端点:将 Bun 的 S3Client 与 AWS S3 一起使用
AWS S3 是默认选项。对于 AWS S3,您也可以传递region 选项而不是 endpoint 选项。
将 Bun 的 S3Client 与 Google Cloud Storage 一起使用
要将 Bun 的 S3 客户端与 Google Cloud Storage 一起使用,在S3Client 构造函数中将 endpoint 设置为 "https://storage.googleapis.com"。
将 Bun 的 S3Client 与 Cloudflare R2 一起使用
要将 Bun 的 S3 客户端与 Cloudflare R2 一起使用,在S3Client 构造函数中将 endpoint 设置为 R2 端点。R2 端点包含您的账户 ID。
将 Bun 的 S3Client 与 DigitalOcean Spaces 一起使用
要将 Bun 的 S3 客户端与 DigitalOcean Spaces 一起使用,在S3Client 构造函数中将 endpoint 设置为 DigitalOcean Spaces 端点。
将 Bun 的 S3Client 与 MinIO 一起使用
要将 Bun 的 S3 客户端与 MinIO 一起使用,在S3Client 构造函数中将 endpoint 设置为 MinIO 运行的 URL。
将 Bun 的 S3Client 与 supabase 一起使用
要将 Bun 的 S3 客户端与 supabase 一起使用,在S3Client 构造函数中将 endpoint 设置为 supabase 端点。supabase 端点包含您的账户 ID 和 /storage/v1/s3 路径。确保在 supabase 仪表板的 https://supabase.com/dashboard/project/<account-id>/settings/storage 中启用 S3 协议连接,并设置在同一部分中告知的区域。
将 Bun 的 S3Client 与 S3 虚拟主机样式端点一起使用
使用 S3 虚拟主机样式端点时,需要将virtualHostedStyle 选项设置为 true。
- 如果您不指定端点,Bun 将根据提供的区域和 存储桶自动确定 AWS S3 端点。 - 如果未指定区域,Bun 默认为 us-east-1。 - 如果您明确提供端点,则 无需指定存储桶名称。
凭据
凭据是使用 S3 最困难的部分之一,我们已尽力使其尽可能简单。默认情况下,Bun 从以下环境变量读取凭据。| 选项名称 | 环境变量 |
|---|---|
accessKeyId | S3_ACCESS_KEY_ID |
secretAccessKey | S3_SECRET_ACCESS_KEY |
region | S3_REGION |
endpoint | S3_ENDPOINT |
bucket | S3_BUCKET |
sessionToken | S3_SESSION_TOKEN |
S3_* 环境变量,Bun 还会为上述每个选项检查 AWS_* 环境变量。
| 选项名称 | 后备环境变量 |
|---|---|
accessKeyId | AWS_ACCESS_KEY_ID |
secretAccessKey | AWS_SECRET_ACCESS_KEY |
region | AWS_REGION |
endpoint | AWS_ENDPOINT |
bucket | AWS_BUCKET |
sessionToken | AWS_SESSION_TOKEN |
process.env 不用于此目的)。
这些默认值会被您传递给 s3.file(credentials)、new Bun.S3Client(credentials) 或任何接受凭据的方法的选项所覆盖。因此,如果例如您对不同的存储桶使用相同的凭据,您可以在 .env 文件中设置一次凭据,然后传递 bucket: "my-bucket" 给 s3.file() 函数,而无需再次指定所有凭据。
S3Client 对象
当您不使用环境变量或使用多个存储桶时,您可以创建一个 S3Client 对象来显式设置凭据。
S3Client.prototype.write
要上传或写入文件到 S3,请在 S3Client 实例上调用 write。
S3Client.prototype.delete
要从 S3 删除文件,请在 S3Client 实例上调用 delete。
S3Client.prototype.exists
要检查 S3 中是否存在文件,请在 S3Client 实例上调用 exists。
S3File
S3File 实例通过调用 S3Client 实例方法或 s3.file() 函数创建。与 Bun.file() 类似,S3File 实例是懒惰的。它们不一定指向创建时就存在的东西。这就是为什么所有不涉及网络请求的方法都是完全同步的原因。
Bun.file() 类似,S3File 扩展了 Blob,因此所有在 Blob 上可用的方法在 S3File 上也可用。用于从本地文件读取数据的相同 API 也可用于从 S3 读取数据。
| 方法 | 输出 |
|---|---|
await s3File.text() | string |
await s3File.bytes() | Uint8Array |
await s3File.json() | JSON |
await s3File.stream() | ReadableStream |
await s3File.arrayBuffer() | ArrayBuffer |
S3File 实例与 fetch()、Response 和其他接受 Blob 实例的 Web API 一起使用即可。
使用 slice 进行部分读取
要读取文件的部分范围,您可以使用 slice 方法。
Range 头来仅请求您想要的字节来工作。此 slice 方法与 Blob.prototype.slice 相同。
从 S3 删除文件
要从 S3 删除文件,您可以使用delete 方法。
delete 与 unlink 相同。
错误代码
当 Bun 的 S3 API 抛出错误时,它将有一个code 属性,与以下值之一匹配:
ERR_S3_MISSING_CREDENTIALSERR_S3_INVALID_METHODERR_S3_INVALID_PATHERR_S3_INVALID_ENDPOINTERR_S3_INVALID_SIGNATUREERR_S3_INVALID_SESSION_TOKEN
S3Error 实例(名称为 "S3Error" 的 Error 实例)。
S3Client 静态方法
S3Client 类提供了几个用于与 S3 交互的静态方法。
S3Client.write(静态)
要直接写入数据到存储桶中的路径,您可以使用 S3Client.write 静态方法。
new S3Client(credentials).write("my-file.txt", "Hello World")。
S3Client.presign(静态)
要为 S3 文件生成预签名 URL,您可以使用 S3Client.presign 静态方法。
new S3Client(credentials).presign("my-file.txt", { expiresIn: 3600 })。
S3Client.list(静态)
要列出存储桶中的某些或全部(最多 1,000 个)对象,您可以使用 S3Client.list 静态方法。
new S3Client(credentials).list()。
S3Client.exists(静态)
要检查 S3 文件是否存在,您可以使用 S3Client.exists 静态方法。
S3File 实例。
S3Client.size(静态)
要快速检查 S3 文件的大小而不下载它,您可以使用 S3Client.size 静态方法。
new S3Client(credentials).size("my-file.txt")。
S3Client.stat(静态)
要获取 S3 文件的大小、etag 和其他元数据,您可以使用 S3Client.stat 静态方法。
S3Client.delete(静态)
要删除 S3 文件,您可以使用 S3Client.delete 静态方法。
s3:// 协议
为了更轻松地使用本地文件和 S3 文件的相同代码,s3:// 协议在 fetch 和 Bun.file() 中得到支持。
s3 选项附加到 fetch 和 Bun.file 函数。
UTF-8、UTF-16 和 BOM(字节顺序标记)
与Response 和 Blob 类似,S3File 默认假定 UTF-8 编码。
调用 S3File 的 text() 或 json() 方法之一时:
- 检测到 UTF-16 字节顺序标记(BOM)时,它将被视为 UTF-16。JavaScriptCore 本机支持 UTF-16,因此它会跳过 UTF-8 转码过程(并剥离 BOM)。这通常是好的,但这确实意味着如果您的 UTF-16 字符串中有无效的代理对字符,它们将被传递给 JavaScriptCore(与源代码相同)。
- 检测到 UTF-8 BOM 时,在将字符串传递给 JavaScriptCore 之前会将其剥离,并将无效的 UTF-8 代码点替换为 Unicode 替换字符(
\uFFFD)。 - 不支持 UTF-32。