Todos los productos
Search
Centro de documentos

Object Storage Service:Carga mediante formulario

Última actualización: Sep 03, 2026

La carga mediante formulario permite cargar objetos directamente a Object Storage Service (OSS) con formularios HTML estándar desde aplicaciones web. Este tema describe cómo generar información como una firma y una directiva de carga mediante el SDK de OSS para Go 2.0, y cómo usar el método HTTP Post para cargar un objeto en OSS.

Notas de uso

  • El código de ejemplo de este tema usa el ID de región cn-hangzhou correspondiente a la región China (Hangzhou). De forma predeterminada, se usa el endpoint público para acceder a los recursos de un bucket. Si desea acceder a los recursos del bucket mediante otros servicios de Alibaba Cloud en la misma región donde se encuentra el bucket, use el endpoint interno. Para obtener más información sobre las regiones y los endpoints de OSS, consulte Regions and endpoints.

  • En este tema, las credenciales de acceso se obtienen de variables de entorno. Para obtener más información sobre cómo configurar las credenciales de acceso, consulte Configure access credentials.

  • El tamaño del objeto que se carga mediante un formulario no puede superar los 5 GB.

Ejemplos

A continuación se presenta un código de ejemplo que muestra cómo cargar mediante formulario. El proceso completo consta de los siguientes pasos:

  1. **Crear una directiva de carga**: Especifique el periodo de validez y las condiciones de una solicitud de carga, incluido el nombre del bucket, la versión de la firma, las credenciales, la fecha de la solicitud y el rango de longitud del cuerpo de la solicitud.

  2. Procesar la directiva de carga: Convierta la directiva de carga a una cadena JSON y codifíquela en Base64.

  3. Generar una clave de firma: Use el algoritmo HMAC-SHA256 para generar una clave de firma que incluya la fecha, la región, el servicio y el tipo de solicitud.

  4. Calcular una firma: Use la clave de firma generada para firmar la cadena de la directiva codificada en Base64 y convierta la firma a una cadena hexadecimal.

  5. Construir un cuerpo de solicitud: Cree un escritor de formularios multipart, especifique la clave del objeto, la directiva, la versión de la firma, las credenciales, la fecha de la solicitud y la firma en el formulario, y escriba los datos que desea cargar en dicho formulario.

  6. Crear y ejecutar una solicitud: Cree una solicitud HTTP POST y especifique los encabezados de la solicitud. Envíe la solicitud y compruebe el código de estado de la respuesta para asegurarse de que la solicitud se haya completado correctamente.

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"))
}

Referencias

  • Para consultar el código de ejemplo completo para cargar mediante formulario, visite GitHub.