接入 SDK 时,真正影响后续维护成本的不是几行初始化代码,而是是否在一开始就把密钥、桶名、文件路径和权限边界梳理清楚。下面这些示例可直接作为项目起步模板。
已经拿到接入域名和访问密钥时,本页即可直接用于落地代码。它不只是展示几段 SDK 片段,而是说明哪种语言适合什么场景、初始化代码应如何收口、前端上传为何必须走服务端签名,以及何时应考虑分段上传。
建议先选择一门最贴近现有业务栈的语言,把最小上传和下载跑通,再把这里的服务封装方式、路径规划和安全说明纳入项目规范。
适合 Next.js、Node.js、BFF、后台管理系统和自动化脚本。当前后端主力栈以 Web 为主时,这通常是第一选择。
适合数据清洗、AI 训练、批处理、媒体管线、知识库任务。存储服务更多被模型、脚本和任务机访问时,Python 会更顺手。
适合高并发服务、网关、中间层和内部工具。对高性能和部署稳定性要求较高时,Go 是很稳的生产方案。
SDK 示例真正依赖的控制台信息主要就两类:一类是密钥,一类是测试桶。先把这两类信息准备齐,再开始复制示例代码。
控制台下发接入域名与访问密钥,业务服务按标准 S3 SDK 接入。
浏览器和移动端只拿授权结果,不直接保存长期密钥。
文件路径按业务、环境、日期规划,便于迁移、审计和归档。
适合 Next.js、Node.js 服务端、后台任务和自动化脚本。
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { readFileSync } from 'node:fs';
const client = new S3Client({
region: 'auto',
endpoint: process.env.SURUN_S3_ENDPOINT,
credentials: {
accessKeyId: process.env.SURUN_ACCESS_KEY_ID!,
secretAccessKey: process.env.SURUN_SECRET_ACCESS_KEY!,
},
});
await client.send(
new PutObjectCommand({
Bucket: 'media-assets',
Key: 'demo/hello.txt',
Body: readFileSync('./hello.txt'),
ContentType: 'text/plain',
}),
);适合数据处理、AI 训练、模型同步和离线任务。
import os
import boto3
session = boto3.session.Session()
client = session.client(
's3',
endpoint_url=os.environ['SURUN_S3_ENDPOINT'],
aws_access_key_id=os.environ['SURUN_ACCESS_KEY_ID'],
aws_secret_access_key=os.environ['SURUN_SECRET_ACCESS_KEY'],
region_name='auto',
)
client.upload_file(
'weights/model.safetensors',
'training-assets',
'models/model.safetensors',
)适合高并发服务、微服务网关和内部工具。
package main
import (
"context"
"os"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
client, _ := minio.New(os.Getenv("SURUN_S3_ENDPOINT"), &minio.Options{
Creds: credentials.NewStaticV4(os.Getenv("SURUN_ACCESS_KEY_ID"), os.Getenv("SURUN_SECRET_ACCESS_KEY"), ""),
Secure: true,
})
client.FPutObject(context.Background(), "media-assets", "demo/video.mp4", "./video.mp4", minio.PutObjectOptions{})
}不建议把 SDK 代码直接散落在业务接口里。更稳的方式是封成统一的 `storageService`,让上传授权、下载授权和基础对象操作走同一套模块。
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
const client = new S3Client({
region: 'auto',
endpoint: process.env.SURUN_S3_ENDPOINT,
credentials: {
accessKeyId: process.env.SURUN_ACCESS_KEY_ID!,
secretAccessKey: process.env.SURUN_SECRET_ACCESS_KEY!,
},
});
export const storageService = {
async createUploadUrl(objectKey: string, contentType: string) {
return getSignedUrl(
client,
new PutObjectCommand({
Bucket: process.env.SURUN_DEFAULT_BUCKET!,
Key: objectKey,
ContentType: contentType,
}),
{ expiresIn: 600 },
);
},
async createDownloadUrl(objectKey: string) {
return getSignedUrl(
client,
new GetObjectCommand({
Bucket: process.env.SURUN_DEFAULT_BUCKET!,
Key: objectKey,
}),
{ expiresIn: 300 },
);
},
};浏览器上传的正确方式不是把 SDK 和长期密钥塞进前端,而是通过业务后端接口申请授权上传地址。
export async function uploadFromBrowser(file: File) {
const response = await fetch('/api/storage/presign-upload', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
fileName: file.name,
contentType: file.type,
}),
});
const { uploadUrl } = await response.json();
await fetch(uploadUrl, {
method: 'PUT',
headers: {
'Content-Type': file.type,
},
body: file,
});
}可以作为起步模板,但建议把桶名、文件前缀、Content-Type 校验和错误处理再按业务封装一层,不要直接散落在各个接口里。
因为浏览器不适合持有长期密钥。正式方案应由前端向业务后端申请授权链接,再由浏览器完成上传。
按现有业务栈选择即可。关键不在语言,而在是否把密钥、文件路径规划和权限边界统一管理起来。
文档中心帮助你完成接入,客户服务页帮助你了解采购、支持与服务信息。