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
上一篇 12小时前
下一篇 1天前

相关推荐

  • 编程基础 0005_错误处理进阶

    Go 错误处理进阶 目录 Go 错误处理哲学 error 接口本质 自定义错误类型 fmt.Errorf 与 %w 包装错误 errors.Is 和 errors.As 哨兵错误模式 错误处理最佳实践 实际项目中的错误处理模式 1. Go 错误处理哲学 1.1 与 try-catch 的根本区别 在 Java、Python、C++ 等语言中,异常处理依赖 t…

    后端开发 16小时前
    700
  • Go工程师体系课 015

    Docker 容器化 —— Go 项目实战指南 一、Docker 核心概念 1.1 什么是 Docker Docker 是一个开源的容器化平台,它可以将应用程序及其所有依赖项打包到一个标准化的单元(容器)中,从而实现"一次构建,到处运行"。对于 Go 开发者而言,Docker 解决了以下痛点: 开发环境与生产环境不一致 依赖管理复杂(数据库、缓存、消息队列等…

    后端开发 4分钟前
    000
  • 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:社区维护的官…

  • Go工程师体系课 010

    es 安装 elasticsearch(理解为库) kibana(理解为连接工具)es 和 kibana(5601) 的版本要保持一致 MySQL 对照学习 Elasticsearch(ES) 术语对照 MySQL Elasticsearch database index(索引) table type(7.x 起固定为 _doc,8.x 彻底移除多 type…

    后端开发 5小时前
    100
  • 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 …

简体中文 繁体中文 English