全部产品
Search
文档中心

Object Storage Service:Unggah formulir

更新时间:Jun 26, 2025

Unggah formulir memungkinkan Anda mengunggah objek langsung ke Object Storage Service (OSS) menggunakan formulir HTML standar dari aplikasi web. Topik ini menjelaskan cara menghasilkan informasi seperti tanda tangan dan kebijakan unggah dengan menggunakan OSS SDK for Go 2.0 serta cara menggunakan metode HTTP POST untuk mengunggah objek ke OSS.

Catatan penggunaan

  • Kode contoh dalam topik ini menggunakan ID wilayah cn-hangzhou untuk wilayah Hangzhou, Tiongkok. Secara default, titik akhir publik digunakan untuk mengakses sumber daya di bucket. Jika Anda ingin mengakses sumber daya di bucket melalui layanan Alibaba Cloud lainnya di wilayah yang sama, gunakan titik akhir internal. Untuk informasi lebih lanjut tentang wilayah dan titik akhir OSS, lihat Wilayah dan Titik Akhir.

  • Dalam topik ini, kredensial akses diperoleh dari variabel lingkungan. Untuk informasi lebih lanjut tentang cara mengonfigurasi kredensial akses, lihat Konfigurasi Kredensial Akses.

  • Ukuran objek yang ingin diunggah menggunakan unggah formulir tidak boleh melebihi 5 GB.

Contoh

Berikut adalah kode contoh yang menunjukkan cara melakukan unggah formulir. Proses lengkap unggah formulir terdiri dari langkah-langkah berikut:

  1. Buat Kebijakan Unggah: Tentukan periode validitas dan kondisi permintaan unggah, termasuk nama bucket, versi tanda tangan, kredensial, tanggal permintaan, dan rentang panjang badan permintaan.

  2. Proses Kebijakan Unggah: Ubah kebijakan unggah menjadi string JSON dan enkode string tersebut dalam Base64.

  3. Hasilkan Kunci Penandatanganan: Gunakan algoritma HMAC-SHA256 untuk menghasilkan kunci penandatanganan yang mencakup tanggal, wilayah, layanan, dan jenis permintaan.

  4. Hitung Tanda Tangan: Gunakan kunci penandatanganan yang dihasilkan untuk menandatangani string kebijakan yang dienkripsi dalam Base64 dan ubah tanda tangan menjadi string heksadesimal.

  5. Bangun Badan Permintaan: Buat penulis formulir multipart, tentukan kunci objek, kebijakan, versi tanda tangan, kredensial, tanggal permintaan, dan tanda tangan dalam formulir, serta tulis data yang ingin diunggah ke formulir.

  6. Buat dan Eksekusi Permintaan: Buat permintaan HTTP POST dan tentukan header permintaan. Kirim permintaan dan periksa kode status respons untuk memastikan bahwa permintaan berhasil.

package main

import (
	"bytes"
	"context"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"flag"
	"fmt"
	"hash"
	"io"
	"log"
	"mime/multipart"
	"net/http"
	"time"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

var (
	region     string // Wilayah tempat bucket berada.
	bucketName string // Nama bucket.
	objectName string // Nama objek.
	product    = "oss"
)

// Tentukan fungsi init yang digunakan untuk menginisialisasi parameter baris perintah.
func init() {
	flag.StringVar(&region, "region", "", "Wilayah tempat bucket berada.")
	flag.StringVar(&bucketName, "bucket", "", "Nama bucket.")
	flag.StringVar(&objectName, "object", "", "Nama objek.")
}

func main() {
	// Parsing parameter baris perintah.
	flag.Parse()

	// Periksa apakah nama bucket kosong.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("parameter tidak valid, nama bucket diperlukan")
	}

	// Periksa apakah wilayah kosong.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("parameter tidak valid, wilayah diperlukan")
	}

	// Periksa apakah nama objek kosong.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("parameter tidak valid, nama objek diperlukan")
	}

	// Buat penyedia kredensial.
	credentialsProvider := credentials.NewEnvironmentVariableCredentialsProvider()
	cred, err := credentialsProvider.GetCredentials(context.TODO())
	if err != nil {
		log.Fatalf("GetCredentials gagal, err:%v", err)
	}

	// Tentukan konten yang ingin Anda unggah.
	content := "hi oss"

	// Buat kebijakan unggah.
	utcTime := time.Now().UTC()
	date := utcTime.Format("20060102")
	expiration := utcTime.Add(1 * time.Hour)
	policyMap := map[string]any{
		"expiration": expiration.Format("2006-01-02T15:04:05.000Z"),
		"conditions": []any{
			map[string]string{"bucket": bucketName},
			map[string]string{"x-oss-signature-version": "OSS4-HMAC-SHA256"},
			map[string]string{"x-oss-credential": fmt.Sprintf("%v/%v/%v/%v/aliyun_v4_request",
				cred.AccessKeyID, date, region, product)}, // Tentukan kredensial.
			map[string]string{"x-oss-date": utcTime.Format("20060102T150405Z")},
			// Tentukan kondisi lainnya.
			[]any{"content-length-range", 1, 1024},
			// []any{"eq", "$success_action_status", "201"},
			// []any{"starts-with", "$key", "user/eric/"},
			// []any{"in", "$content-type", []string{"image/jpg", "image/png"}},
			// []any{"not-in", "$cache-control", []string{"no-cache"}},
		},
	}

	// Ubah kebijakan unggah menjadi string JSON.
	policy, err := json.Marshal(policyMap)
	if err != nil {
		log.Fatalf("json.Marshal gagal, err:%v", err)
	}

	// Enkode string JSON dalam Base64.
	stringToSign := base64.StdEncoding.EncodeToString([]byte(policy))

	// Hasilkan kunci penandatanganan.
	hmacHash := func() hash.Hash { return sha256.New() }
	signingKey := "aliyun_v4" + cred.AccessKeySecret
	h1 := hmac.New(hmacHash, []byte(signingKey))
	io.WriteString(h1, date)
	h1Key := h1.Sum(nil)

	h2 := hmac.New(hmacHash, h1Key)
	io.WriteString(h2, region)
	h2Key := h2.Sum(nil)

	h3 := hmac.New(hmacHash, h2Key)
	io.WriteString(h3, product)
	h3Key := h3.Sum(nil)

	h4 := hmac.New(hmacHash, h3Key)
	io.WriteString(h4, "aliyun_v4_request")
	h4Key := h4.Sum(nil)

	// Hitung tanda tangan.
	h := hmac.New(hmacHash, h4Key)
	io.WriteString(h, stringToSign)
	signature := hex.EncodeToString(h.Sum(nil))

	// Bangun badan permintaan Post.
	bodyBuf := &bytes.Buffer{}

	// Buat penulis formulir multipart untuk membangun badan permintaan.
	bodyWriter := multipart.NewWriter(bodyBuf)

	// Tentukan informasi objek, termasuk kunci dan metadata.
	bodyWriter.WriteField("key", objectName) // Tentukan kunci objek (nama objek).
	// bodyWriter.WriteField("x-oss-", value) // Tentukan metadata. Parameter ini opsional.

	// Tentukan string kebijakan yang dienkripsi dalam Base64.
	bodyWriter.WriteField("policy", stringToSign)

	// Tentukan versi tanda tangan.
	bodyWriter.WriteField("x-oss-signature-version", "OSS4-HMAC-SHA256")

	// Tentukan kredensial.
	bodyWriter.WriteField("x-oss-credential", fmt.Sprintf("%v/%v/%v/%v/aliyun_v4_request", cred.AccessKeyID, date, region, product))

	// Tentukan tanggal permintaan.
	bodyWriter.WriteField("x-oss-date", utcTime.Format("20060102T150405Z"))

	// Tentukan tanda tangan.
	bodyWriter.WriteField("x-oss-signature", signature)

	// Buat bidang formulir bernama "file" untuk mengunggah data.
	w, _ := bodyWriter.CreateFormField("file")

	// Tulis data yang ingin Anda unggah ke bidang formulir.
	w.Write([]byte(content))

	// Tutup penulis formulir dan pastikan semua data ditulis ke badan permintaan sesuai harapan.
	bodyWriter.Close()

	// Buat permintaan Post.
	req, _ := http.NewRequest("POST", fmt.Sprintf("http://%v.oss-%v.aliyuncs.com/", bucketName, region), bodyBuf)
	req.Header.Set("Content-Type", bodyWriter.FormDataContentType())

	// Eksekusi permintaan Post.
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("Do gagal, err:%v", err)
	}
	defer resp.Body.Close()

	// Periksa kode status respons.
	if resp.StatusCode/100 != 2 {
		log.Fatalf("Post Objek Gagal, kode status:%v, alasan:%v", resp.StatusCode, resp.Status)
	}

	log.Printf("post objek selesai, kode status:%v, request id:%v\n", resp.StatusCode, resp.Header.Get("X-Oss-Request-Id"))
}

Referensi

  • Untuk kode contoh lengkap yang digunakan untuk melakukan unggah formulir, kunjungi GitHub.