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)限制 | 限制可訪問的來源網站 |
正文完