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