前置作業
先到 AWS IAM 建立一個使用者,打開「Security credentials」頁籤,並選擇「Create access key」按鈕,最後將生成的「Access key ID」和「Secret access key」儲存起來。
實作
建立專案。
1 2
| mkdir go-s3-example cd go-s3-example
|
初始化 Go Modules。
1
| go mod init github.com/memochou1993/go-s3-example
|
下載 aws-sdk-go
套件。
1
| go get github.com/aws/aws-sdk-go/aws
|
新增 main.go
檔,填入必要變數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| var ( AccessKeyID = "" SecretAccessKey = "" Region = "" Bucket = "" )
func main() { sess := ConnectAws()
http.Handle("/", http.FileServer(http.Dir("./public")))
http.HandleFunc("/upload-file", func(w http.ResponseWriter, r *http.Request) { r.ParseMultipartForm(32 << 20) for _, fileHeaders := range r.MultipartForm.File { for _, header := range fileHeaders { Upload(sess, Bucket, header) } } })
http.HandleFunc("/upload-files", func(w http.ResponseWriter, r *http.Request) { r.ParseMultipartForm(32 << 20) for _, fileHeaders := range r.MultipartForm.File { UploadMultiple(sess, Bucket, fileHeaders) } })
log.Fatal(http.ListenAndServe(":8080", nil)) }
|
新增 ConnectAws
方法,用來取得一個 Session:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func ConnectAws() *session.Session { sess, err := session.NewSession(&aws.Config{ Region: aws.String(Region), Credentials: credentials.NewStaticCredentials( AccessKeyID, SecretAccessKey, "", ), }) if err != nil { panic(err) } return sess }
|
新增 Upload
方法,用來上傳單一檔案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| func Upload(sess *session.Session, bucket string, header *multipart.FileHeader) error { svc := s3manager.NewUploader(sess) src, err := header.Open() if err != nil { return err } if _, err := svc.Upload(&s3manager.UploadInput{ Bucket: aws.String(bucket), ACL: aws.String("public-read"), Key: aws.String(header.Filename), Body: src, }); err != nil { return err } return nil }
|
新增 UploadMultiple
方法,用來上傳多個檔案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| func UploadMultiple(sess *session.Session, bucket string, fileHeaders []*multipart.FileHeader) error { var objects []s3manager.BatchUploadObject for _, header := range fileHeaders { src, err := header.Open() if err != nil { return err } objects = append(objects, s3manager.BatchUploadObject{ Object: &s3manager.UploadInput{ Bucket: aws.String(bucket), ACL: aws.String("public-read"), Key: aws.String(header.Filename), Body: src, }, }) } svc := s3manager.NewUploader(sess) iter := &s3manager.UploadObjectsIterator{Objects: objects} return svc.UploadWithIterator(aws.BackgroundContext(), iter) }
|
在 public
資料夾新增 index.html
檔,當作表單:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form method="POST" action="/upload-file" enctype="multipart/form-data"> <input type="file" name="files[]"> <input type="submit"> </form> <form method="POST" action="/upload-files" enctype="multipart/form-data"> <input type="file" name="files[]" multiple> <input type="submit"> </form> </body> </html>
|
執行。
前端
使用 Axios 上傳檔案,範例如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> </head> <body id="app"> <input id="file" type="file"> <button onclick="upload()">Upload</button> <script> const upload = async () => { const file = document.getElementById('file').files[0]; const formData = new FormData(); formData.append('files[]', file); const res = await axios('https://localhost:8080/upload-file', { method: 'POST', headers: { 'Content-Type': 'multipart/form-data', }, data: formData, }); console.log(res); const img = document.createElement('img'); img.setAttribute('src', `${res.data.data.avatar}?t=${+new Date()}`); document.getElementById('app').appendChild(img); }; </script> </body> </html>
|
瀏覽網頁
前往 http://127.0.0.1:8080 瀏覽。
參考資料