Tous les produits
Search
Centre de documentation

Object Storage Service:Form upload

Dernière mise à jour :Aug 18, 2026

Le téléchargement via formulaire permet de charger directement des objets vers Object Storage Service (OSS) à l'aide de formulaires HTML standard depuis des applications web. Cette rubrique explique comment générer des informations telles qu'une signature et une politique de téléchargement avec OSS SDK for Go 2.0, puis utiliser la méthode HTTP POST pour charger un objet vers OSS.

Remarques d'utilisation

  • L'exemple de code de cette rubrique utilise l'ID de région cn-hangzhou de la région Chine (Hangzhou). Par défaut, le point de terminaison public sert à accéder aux ressources d'un bucket. Pour accéder aux ressources du bucket via d'autres services Alibaba Cloud situés dans la même région, utilisez le point de terminaison interne. Pour plus d'informations sur les régions et les points de terminaison OSS, consultez Régions et points de terminaison.

  • Dans cette rubrique, les identifiants d'accès proviennent des variables d'environnement. Pour savoir comment configurer les identifiants d'accès, consultez Configurer les identifiants d'accès.

  • La taille de l'objet chargé via un formulaire ne doit pas dépasser 5 Go.

Exemples

L'exemple de code suivant illustre la procédure de téléchargement via formulaire. Le processus complet se décompose comme suit :

  1. **Créez une politique de téléchargement** : spécifiez la période de validité et les conditions d'une requête de téléchargement, y compris le nom du bucket, la version de la signature, les identifiants, la date de la requête et la plage de longueur du corps de la requête.

  2. Traitez la politique de téléchargement : convertissez la politique de téléchargement en chaîne JSON, puis encodez cette chaîne en Base64.

  3. Générez une clé de signature : utilisez l'algorithme HMAC-SHA256 pour générer une clé de signature incluant la date, la région, le service et le type de requête.

  4. Calculez une signature : utilisez la clé de signature générée pour signer la chaîne de politique encodée en Base64, puis convertissez la signature en chaîne hexadécimale.

  5. Construisez un corps de requête : créez un rédacteur de formulaire multipart, spécifiez la clé de l'objet, la politique, la version de la signature, les identifiants, la date de la requête et la signature dans le formulaire, puis écrivez les données à charger dans le formulaire.

  6. Créez et exécutez une requête : créez une requête HTTP POST et spécifiez les en-têtes de requête. Envoyez la requête et vérifiez le code d'état de la réponse pour vous assurer que la requête a abouti.

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 // The region in which the bucket is located.
	bucketName string // The name of the bucket.
	objectName string // The name of the object.
	product    = "oss"
)

// Specify the init function used to initialize command line parameters.
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// Parse command line parameters.
	flag.Parse()

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// Create a credential provider.
	credentialsProvider := credentials.NewEnvironmentVariableCredentialsProvider()
	cred, err := credentialsProvider.GetCredentials(context.TODO())
	if err != nil {
		log.Fatalf("GetCredentials fail, err:%v", err)
	}

	// Specify the content that you want to upload.
	content := "hi oss"

	// Create an upload policy.
	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)}, // Specify the credentials.
			map[string]string{"x-oss-date": utcTime.Format("20060102T150405Z")},
			// Specify other conditions.
			[]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"}},
		},
	}

	// Convert the upload policy to a JSON string.
	policy, err := json.Marshal(policyMap)
	if err != nil {
		log.Fatalf("json.Marshal fail, err:%v", err)
	}

	// Base64-encode the JSON string.
	stringToSign := base64.StdEncoding.EncodeToString([]byte(policy))

	// Generate a signing key.
	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)

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

	// Build a Post request body.
	bodyBuf := &bytes.Buffer{}

	// Create a multipart form writer to build the request body.
	bodyWriter := multipart.NewWriter(bodyBuf)

	// Specify the object information, including the key and metadata.
	bodyWriter.WriteField("key", objectName) // Specify the object key (object name).
	// bodyWriter.WriteField("x-oss-", value) // Specify the metadata. This parameter is optional.

	// Specify the Base64-encoded policy string.
	bodyWriter.WriteField("policy", stringToSign)

	// Specify the signature version.
	bodyWriter.WriteField("x-oss-signature-version", "OSS4-HMAC-SHA256")

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

	// Specify the request date.
	bodyWriter.WriteField("x-oss-date", utcTime.Format("20060102T150405Z"))

	// Specify the signature.
	bodyWriter.WriteField("x-oss-signature", signature)

	// Create a form field named "file" to upload data.
	w, _ := bodyWriter.CreateFormField("file")

	// Write the data that you want to upload to the form field.
	w.Write([]byte(content))

	// Close the form writer and make sure that all data is written to the request body as expected.
	bodyWriter.Close()

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

	// Execute the Post request.
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("Do fail, err:%v", err)
	}
	defer resp.Body.Close()

	// Check the response status code.
	if resp.StatusCode/100 != 2 {
		log.Fatalf("Post Object Fail, status code:%v, reason:%v", resp.StatusCode, resp.Status)
	}

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

Références

  • Pour consulter l'exemple de code complet utilisé pour effectuer un téléchargement via formulaire, rendez-vous sur GitHub.