存储
学习如何设置和使用云存储进行文件上传和媒体处理
MkSaaS 使用 Amazon S3 和兼容 S3 的服务(如 Cloudflare R2)进行文件存储和媒体处理,为存储图像和其他媒体文件提供可靠且可扩展的解决方案。
设置
要在 MkSaaS 中设置存储,请按照以下步骤配置必要的环境变量:
Cloudflare R2(推荐)
- 在 cloudflare.com 创建 Cloudflare 账户
- 创建新的 R2 存储桶:
- 选择全局唯一的存储桶名称(例如
your-project-name
) - 选择靠近目标受众的区域
- 根据您的需要设置其他选项
- 选择全局唯一的存储桶名称(例如
- 允许对存储桶的公共访问:
Settings
>Public Development URL
,点击启用
- 将公共访问 URL 保存为
STORAGE_PUBLIC_URL
- 为存储桶的公共访问设置自定义域名
- 创建新的 API 令牌:
R2
>API
>Manage API Tokens
,点击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://pub-xxx.r2.dev
- 更新网站配置以使用 R2 作为存储提供商:
export const websiteConfig = {
// ...其他配置
storage: {
provider: 's3',
},
// ...其他配置
}
将存储提供商设置为 s3
,因为 Cloudflare R2 与 Amazon S3 兼容。
Amazon S3
-
在 aws.amazon.com 创建 AWS 账户
-
创建新的 S3 存储桶:
- 选择全局唯一的存储桶名称(例如
your-project-name
) - 选择靠近目标受众的区域
- 如果您希望文件可公开访问,禁用
Block all public access
选项 - 根据您的需要设置其他选项
- 选择全局唯一的存储桶名称(例如
-
添加存储桶策略以允许公共访问,进入到
Permissions
选项卡并添加:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
-
创建具有 S3 访问权限的 IAM 用户:
- 导航到 IAM 服务
- 创建具有 S3 权限的新策略:
GetObject
、PutObject
、DeleteObject
、ListBucket
- 创建具有
Programmatic access
权限的新 IAM 用户 - 附加您创建的策略
- 保存
Access Key ID
和Secret Access Key
-
添加以下环境变量:
STORAGE_REGION=your-region
STORAGE_BUCKET_NAME=your-bucket-name
STORAGE_ACCESS_KEY_ID=your-access-key
STORAGE_SECRET_ACCESS_KEY=your-secret-key
- 更新网站配置以使用 S3 作为存储提供商:
export const websiteConfig = {
// ...其他配置
storage: {
provider: 's3',
},
// ...其他配置
}
S3 兼容的替代方案
MkSaaS 与任何 S3 兼容的存储服务兼容,包括:
- Backblaze B2 - 非常经济实惠的选择
- Google Cloud Storage - 具有 Google 基础设施的高性能
- DigitalOcean Spaces - 简单定价并与 DigitalOcean 基础设施集成
使用这些替代方案时,请确保在环境变量中设置正确的端点。
如果您正在设置环境,现在可以回到环境配置文档并继续。本文档的其余部分可以稍后阅读。
环境配置
设置环境变量
存储系统架构
MkSaaS 中的存储系统设计包含以下组件:
index.ts
types.ts
client.ts
README.md
这种模块化结构使得使用新提供商和功能扩展存储系统变得容易。
核心功能
- 服务器端的文件上传
- 浏览器端的文件上传
- 支持 Amazon S3 和兼容 S3 的存储服务
- 更好的文件管理,使用文件夹组织文件
- 自动生成路径和文件命名
- 可配置的存储区域和存储桶设置
- 支持公共和私有文件存储
使用方法
基本文件操作
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);
}
}
与表单组件配合使用
以下是将存储模块与表单组件配合使用的示例:
'use client';
import { useState } from 'react';
import { uploadFileFromBrowser } from '@/storage/client';
import { Button } from '@/components/ui/button';
export function ImageUploader() {
const [isUploading, setIsUploading] = useState(false);
const [imageUrl, setImageUrl] = useState<string | null>(null);
async function handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
const file = event.target.files?.[0];
if (!file) return;
try {
setIsUploading(true);
const { url } = await uploadFileFromBrowser(file, 'profile-images');
setImageUrl(url);
} catch (error) {
console.error('上传失败:', error);
} finally {
setIsUploading(false);
}
}
return (
<div className="space-y-4">
<div className="flex items-center gap-4">
<Button
variant="outline"
onClick={() => document.getElementById('file-upload')?.click()}
disabled={isUploading}
>
{isUploading ? '上传中...' : '上传图像'}
</Button>
<input
id="file-upload"
type="file"
accept="image/*"
className="hidden"
onChange={handleFileChange}
/>
</div>
{imageUrl && (
<div className="w-32 h-32 relative">
<img
src={imageUrl}
alt="已上传的图像"
className="object-cover w-full h-full rounded-md"
/>
</div>
)}
</div>
);
}
自定义存储提供商
创建自定义提供商
MkSaaS 使得使用新提供商扩展存储系统变得容易:
-
在
src/storage/provider
目录中创建新文件 -
实现
StorageProvider
接口
import {
PresignedUploadUrlParams,
StorageProvider,
UploadFileParams,
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> {
// 删除文件的实现
}
}
- 在
index.ts
中更新提供商选择:
import { CustomStorageProvider } from './provider/custom-provider';
export const initializeStorageProvider = (): StorageProvider => {
if (!storageProvider) {
if (websiteConfig.storage.provider === 's3') {
storageProvider = new S3Provider();
} else if (websiteConfig.storage.provider === 'custom') {
storageProvider = new CustomStorageProvider();
} else {
throw new Error(
`不支持的存储提供商: ${websiteConfig.storage.provider}`
);
}
}
return storageProvider;
};
最佳实践
- 文件组织:使用文件夹按类型或用途组织文件(例如
uploads/images
、documents/contracts
) - 文件大小限制:设置合理的文件大小限制以防止滥用
- 文件类型验证:在客户端和服务器端验证文件类型以确保安全
视频教程
下一步
现在您了解了如何在 MkSaaS 中使用文件存储,探索这些相关主题: