Go 语言实现文件上传到 AWS S3 示例
本示例演示如何使用 Go 和 AWS SDK v2 将本地文件上传到 Amazon S3。
🧾 前提条件
- 已拥有 AWS 账号;
- 已创建 S3 Bucket;
- 已配置 AWS 凭证(通过
aws configure或设置环境变量); - 已准备本地文件(如
test.jpg);
📦 安装依赖
go mod init s3uploadtest
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/s3
🧑💻 示例代码
package main
import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
bucket := "your-bucket-name" // 替换为你的 S3 桶名
region := "ap-southeast-1" // 替换为你的区域
key := "uploads/test.jpg" // 上传后在 S3 中的路径
filePath := "./test.jpg" // 本地文件路径
// 加载 AWS 配置
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
if err != nil {
log.Fatalf("无法加载 AWS 配置: %v", err)
}
// 创建 S3 客户端
client := s3.NewFromConfig(cfg)
// 打开文件
file, err := os.Open(filePath)
if err != nil {
log.Fatalf("无法打开文件: %v", err)
}
defer file.Close()
// 获取文件大小与内容类型
fileInfo, _ := file.Stat()
size := fileInfo.Size()
contentType := detectContentType(filePath)
// 执行上传
_, err = client.PutObject(context.TODO(), &s3.PutObjectInput{
Bucket: &bucket,
Key: &key,
Body: file,
ContentLength: size,
ContentType: &contentType,
})
if err != nil {
log.Fatalf("上传失败: %v", err)
}
fmt.Println("上传成功 ✅")
fmt.Printf("访问地址: https://%s.s3.amazonaws.com/%s\n", bucket, key)
}
func detectContentType(path string) string {
ext := filepath.Ext(path)
switch ext {
case ".jpg", ".jpeg":
return "image/jpeg"
case ".png":
return "image/png"
case ".gif":
return "image/gif"
case ".txt":
return "text/plain"
default:
return "application/octet-stream"
}
}
✅ 上传验证
上传完成后,访问 URL:
https://your-bucket-name.s3.amazonaws.com/uploads/test.jpg
⚡ 前端直传 + S3 Lambda 回调工作流程
前端直传(Pre-signed URL)结合 S3 Lambda 回调,常用于无需后端中转即可安全上传文件,并在上传后自动触发后续处理。典型流程如下:
-
前端请求后端生成预签名上传 URL
-
前端向后端请求一个带有有效期的 S3 预签名上传 URL(PutObject)。
-
后端根据业务逻辑生成 URL 并返回给前端。
-
前端直传文件到 S3
-
前端使用该 URL 直接将文件上传到 S3,无需经过后端服务器。
-
S3 触发 Lambda 回调
-
S3 配置事件通知(如
s3:ObjectCreated:*),当有新对象上传时自动触发指定的 Lambda 函数。 -
Lambda 处理上传文件
-
Lambda 获取事件信息(如 Bucket、Key、文件元数据)。
-
可进行图片缩略图生成、格式转换、病毒扫描、写入数据库等后续处理。
-
(可选)Lambda 通知业务系统
- Lambda 处理完毕后,可通过 API、消息队列等方式通知业务系统或用户。
示例流程图
前端
│
├─ 请求预签名URL ──► 后端
│ │
│◄── 返回URL ────────┘
│
├─ 直传文件 ─────────► S3
│
└────────────────────► S3 触发 Lambda
│
└─► Lambda 处理/通知
关键点说明
- 预签名 URL 有效期短,权限可控,避免暴露密钥。
- S3 事件通知可配置过滤前缀/后缀,精准触发。
- Lambda 权限需允许读取 S3 对象及访问后续资源。
- 可结合 SNS/SQS 实现异步通知或批量处理。
📚 参考文档
- AWS Go SDK v2 文档: https://pkg.go.dev/github.com/aws/aws-sdk-go-v2
| 建议 | 说明 |
|---|---|
| ✅ 默认关闭公开访问 | S3 提供阻止公共访问功能(默认应开启) |
| ✅ 使用预签名 URL 上传/下载 | 避免对象永久公开 |
| ✅ 不把密钥写入代码或 Git | 使用 .env 或 AWS 的凭证文件 |
| ✅ 给 IAM 用户设置最小权限 | 比如只允许 GetObject 和指定 Bucket |
| ✅ 启用 S3 Access Logging | 记录谁访问了你的文件 |
| ✅ 配置生命周期规则 | 自动清理临时上传的文件 |
| ✅ 设置 S3 跨域(CORS)限制 | 限制可访问的来源网站 |
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/6787