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://www.walker-learn.xyz/archives/6787

(0)
Walker的头像Walker
上一篇 2026年3月6日 02:00
下一篇 2026年3月6日 01:00

相关推荐

  • Go工程师体系课 009

    其它一些功能 个人中心 收藏 管理收货地址(增删改查) 留言 拷贝inventory_srv--> userop_srv 查询替换所有的inventory Elasticsearch 深度解析文档 1. 什么是Elasticsearch Elasticsearch是一个基于Apache Lucene构建的分布式、RESTful搜索和分析引擎,能够快速地…

    后端开发 2026年3月7日
    7100
  • Go工程师体系课 002

    GOPATH 与 Go Modules 的区别 1. 概念 GOPATH 是 Go 的早期依赖管理机制。 所有的 Go 项目和依赖包必须放在 GOPATH 目录中(默认是 ~/go)。 一定要设置 GO111MODULE=off 项目路径必须按照 src/包名 的结构组织。 不支持版本控制,依赖管理需要手动处理(例如 go get)。 查找依赖包的顺序是 g…

    2026年3月7日
    7800
  • 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月7日
    6600
  • Go资深工程师讲解(慕课) 002

    go(二) string 字符串 package main import ( "fmt" "unicode/utf8" ) func main() { s := "Yes我爱Go语言" fmt.Println(len(s)) for _, b := range []byte(s) { fmt.Pri…

    后端开发 2026年3月6日
    7900
  • 编程基础 0001_基础教程

    go 什么是 Go是一门并发支持、垃圾加收的编译型系统编程语言,具有静态编译语言的高性能和动态语言的,主要特点如下 类型安全和内存安全 以非常直观和极低代价的方案实现高并发 高效的垃圾回收机制 快速编译(同时解决了 C 语言中头文件太多的问题) UTF-8 支持 安装 源码安装 标准包安装 第三方安装 标准包安装,一路下一步。安装完后,会自动添加如下环境变量…

    后端开发 2026年3月6日
    6900
简体中文 繁体中文 English