存储
学习如何设置和使用云存储进行文件上传和媒体处理
MkSaaS 使用兼容 Amazon S3 的存储服务(如 Cloudflare R2)进行文件存储。
设置
创建 Cloudflare R2 存储桶(推荐)
- 在 cloudflare.com 创建 Cloudflare 账户
- 创建新的 R2 存储桶:
- 选择全局唯一的存储桶名称(例如
your-project-name) - 选择靠近目标受众的区域
- 根据您的需要设置其他选项
- 选择全局唯一的存储桶名称(例如
启用公共访问
允许对存储桶的公共访问:
Settings>Public Development URL,点击启用- 将公共访问 URL 保存为
STORAGE_PUBLIC_URL - 为存储桶的公共访问设置自定义域名 (推荐使用自定义域名以提高安全性)
创建 API 令牌
创建新的 API 令牌:
Storage & databases>R2 object storage>API Tokens>Manage,点击Create User API Token- 将权限设置为对存储桶的
Object Read & Write - 创建 API 令牌,获取
Access Key ID和Secret Access Key
设置环境变量
设置以下环境变量:
STORAGE_REGION=YOUR-REGION-OR-AUTO
STORAGE_BUCKET_NAME=YOUR-BUCKET-NAME
STORAGE_ACCESS_KEY_ID=YOUR-ACCESS-KEY
STORAGE_SECRET_ACCESS_KEY=YOUR-SECRET-KEY
STORAGE_ENDPOINT=https://xxx.r2.cloudflarestorage.com
STORAGE_PUBLIC_URL=https://your-custom-domain.comS3 兼容的替代方案
MkSaaS 与任何 S3 兼容的存储服务兼容,包括:
- Amazon S3 - 亚马逊的存储服务
- Backblaze B2 - 非常经济实惠的选择
- Google Cloud Storage - 具有 Google 基础设施的高性能
- Digital Ocean Spaces - 简单定价并与 DigitalOcean 基础设施集成
如果您正在设置环境,现在可以回到环境配置文档并继续。本文档的其余部分可以稍后阅读。
环境配置
设置环境变量
使用方法
基本文件操作
MkSaaS 为常见文件操作提供简单的实用程序:
import { uploadFile, deleteFile } from '@/storage';
// 将文件上传到存储
const { url, key } = await uploadFile(
fileBuffer,
'original-filename.jpg',
'image/jpeg',
'uploads/images'
);
// 从存储中删除文件
await deleteFile(key);浏览器端上传文件
要直接从浏览器上传文件,请使用 uploadFileFromBrowser 函数:
'use client';
import { uploadFileFromBrowser } from '@/storage/client';
// 在您的 React 组件中
async function handleFileUpload(event) {
const file = event.target.files[0];
try {
const { url, key } = await uploadFileFromBrowser(file, 'uploads/images');
console.log('文件已上传:', url);
} catch (error) {
console.error('上传失败:', error);
}
}该辅助函数会把 multipart/form-data 发送到受保护的
POST /api/storage/upload 路由,用户必须先登录。内置路由仅接受不超过 4 MB
的 JPEG、PNG 和 WebP 文件;如果产品需要其他限制,请同时修改该路由和
MAX_FILE_SIZE。模板使用的 s3mini 提供商不生成预签名上传 URL,因此浏览器
上传会经过服务端转发。
扩展新的存储提供商
MkSaaS 支持扩展新的存储服务提供商:
-
在
src/storage/provider目录中创建新的文件 -
实现
StorageProvider接口:
import {
type StorageProvider,
type UploadFileParams,
type UploadFileResult,
} from '@/storage/types';
export class CustomStorageProvider implements StorageProvider {
constructor() {
// 初始化您的存储服务提供商
}
public getProviderName(): string {
return 'CustomProvider';
}
async uploadFile(params: UploadFileParams): Promise<UploadFileResult> {
// 上传文件的实现
return { url: 'https://example.com/file.jpg', key: 'file.jpg' };
}
async deleteFile(key: string): Promise<void> {
// 删除文件的实现
}
}- 在
src/types/index.d.ts的StorageConfig['provider']中加入提供商名称, 然后在index.ts注册延迟创建工厂:
import { CustomStorageProvider } from './provider/custom-provider';
const providerRegistry: Partial<
Record<StorageProviderName, StorageProviderFactory>
> = {
s3: () => new S3Provider(),
custom: () => new CustomStorageProvider(),
};
MkSaaS文档