Go日积月累 go-s3-upload-example

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 回调,常用于无需后端中转即可安全上传文件,并在上传后自动触发后续处理。典型流程如下:

  1. 前端请求后端生成预签名上传 URL

  2. 前端向后端请求一个带有有效期的 S3 预签名上传 URL(PutObject)。

  3. 后端根据业务逻辑生成 URL 并返回给前端。

  4. 前端直传文件到 S3

  5. 前端使用该 URL 直接将文件上传到 S3,无需经过后端服务器。

  6. S3 触发 Lambda 回调

  7. S3 配置事件通知(如 s3:ObjectCreated:*),当有新对象上传时自动触发指定的 Lambda 函数。

  8. Lambda 处理上传文件

  9. Lambda 获取事件信息(如 Bucket、Key、文件元数据)。

  10. 可进行图片缩略图生成、格式转换、病毒扫描、写入数据库等后续处理。

  11. (可选)Lambda 通知业务系统

  12. Lambda 处理完毕后,可通过 API、消息队列等方式通知业务系统或用户。

示例流程图

前端
  │
  ├─ 请求预签名URL ──► 后端
  │                    │
  │◄── 返回URL ────────┘
  │
  ├─ 直传文件 ─────────► S3
  │
  └────────────────────► S3 触发 Lambda
                           │
                           └─► Lambda 处理/通知

关键点说明

  • 预签名 URL 有效期短,权限可控,避免暴露密钥。
  • S3 事件通知可配置过滤前缀/后缀,精准触发。
  • Lambda 权限需允许读取 S3 对象及访问后续资源。
  • 可结合 SNS/SQS 实现异步通知或批量处理。

📚 参考文档

建议 说明
✅ 默认关闭公开访问 S3 提供阻止公共访问功能(默认应开启)
✅ 使用预签名 URL 上传/下载 避免对象永久公开
✅ 不把密钥写入代码或 Git 使用 .env 或 AWS 的凭证文件
✅ 给 IAM 用户设置最小权限 比如只允许 GetObject 和指定 Bucket
✅ 启用 S3 Access Logging 记录谁访问了你的文件
✅ 配置生命周期规则 自动清理临时上传的文件
✅ 设置 S3 跨域(CORS)限制 限制可访问的来源网站

主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/6787

(0)
Walker的头像Walker
上一篇 2026年3月8日 15:11
下一篇 2026年3月9日 12:56

相关推荐

  • Go资深工程师讲解(慕课) 005

    005 标准库 http 使用 http 客户端发送请求 使用 http.Client 控制请求头 使用 httputil 简化工作 package main import ( "fmt" "net/http" "net/http/httputil" ) func main() { resp, er…

    后端开发 2026年3月6日
    6000
  • Go工程师体系课 020

    性能优化与 pprof 1. 先测量后优化 "Premature optimization is the root of all evil." — Donald Knuth 优化流程:1. 先写正确的代码2. 用 Benchmark 确认性能瓶颈3. 用 pprof 定位具体位置4. 优化 → 再测量 → 对比 2. pprof 工具 2.1 在 HTTP …

    后端开发 2026年3月6日
    7700
  • Go工程师体系课 006

    项目结构说明:user-web 模块 user-web 是 joyshop_api 工程中的用户服务 Web 层模块,负责处理用户相关的 HTTP 请求、参数校验、业务路由以及调用后端接口等功能。以下是目录结构说明: user-web/ ├── api/ # 控制器层,定义业务接口处理逻辑 ├── config/ # 配置模块,包含系统配置结构体及读取逻辑 …

    后端开发 2026年3月6日
    5100
  • Go工程师体系课 012

    Go 中集成 Elasticsearch 1. 客户端库选择 1.1 主流 Go ES 客户端 olivere/elastic:功能最全面,API 设计优雅,支持 ES 7.x/8.x elastic/go-elasticsearch:官方客户端,轻量级,更接近原生 REST API go-elasticsearch/elasticsearch:社区维护的官…

    后端开发 2026年3月6日
    6200
  • Go工程师体系课 007

    商品微服务 实体结构说明 本模块包含以下核心实体: 商品(Goods) 商品分类(Category) 品牌(Brands) 轮播图(Banner) 品牌分类(GoodsCategoryBrand) 1. 商品(Goods) 描述平台中实际展示和销售的商品信息。 字段说明 字段名 类型 说明 name String 商品名称,必填 brand Pointer …

    后端开发 2026年3月7日
    6000
简体中文 繁体中文 English