Tous les produits
Search
Centre de documentation

Object Storage Service:Téléchargement par formulaire

Dernière mise à jour :Aug 18, 2026

Le téléchargement par formulaire permet aux applications web de charger des objets directement vers OSS via des formulaires HTML standard. Le navigateur envoie une requête PostObject à OSS sans passer par votre serveur d'application, ce qui réduit la charge du serveur et améliore l'efficacité et la stabilité du chargement.

Limites

La taille des objets chargés via un formulaire ne peut pas dépasser 5 Go.

Scénarios

Cas d'utilisation courants du téléchargement par formulaire :

  • Chargement de données utilisateur : chargez des avatars, des photos d'identité ou des documents de vérification d'identité lors de l'inscription ou de la mise à jour du profil.

  • Partage et stockage de fichiers : chargez des documents, des images, des fichiers audio et vidéo vers Alibaba Cloud via des lecteurs en ligne ou des plateformes de collaboration.

  • Publication de contenu : chargez des images et des pièces jointes sur des blogs, des forums et des plateformes de questions-réponses.

  • Commerce électronique : chargez des images de produits, des descriptions et des documents de qualification. Les consommateurs chargent des factures ou des justificatifs lors de leurs achats.

  • Éducation en ligne : les étudiants soumettent leurs devoirs et projets. Les enseignants chargent du matériel pédagogique et des supports de cours.

  • Recrutement : les candidats chargent leur CV et leur portfolio. Les employeurs chargent des logos et des offres d'emploi.

  • Enquêtes et retours : chargez des documents justificatifs ou des preuves avec des questionnaires en ligne.

  • Collaboration au développement : chargez des fichiers de code ou des documents de projet depuis des plateformes telles que GitHub et GitLab.

Fonctionnement

Le client obtient la signature et la politique POST depuis le serveur d'application, puis charge les objets directement sans utiliser les SDK OSS. La politique POST peut restreindre les attributs des objets, tels que la taille et le type. Le téléchargement par formulaire ne prend pas en charge le chargement multipart ni le chargement avec reprise. Pour plus d'informations, consultez PostObject.

Flux de chargement utilisant une signature Post et une politique Post :

image
  1. Le client demande la signature Post, la politique Post et d'autres informations au serveur d'application.

  2. Le serveur d'application génère la signature Post, la politique Post et les informations associées, puis les renvoie au client.

  3. Le client appelle PostObject avec la signature Post et la politique Post pour charger le fichier vers OSS via un formulaire HTML.

  4. OSS renvoie une réponse de succès au client.

Procédure

  1. Générez la signature et la politique POST sur le serveur.

    • Exemple de projet : postsignature.zip

    • Exemples

      Générez la signature Post et la politique Post sur le serveur :

      Remarque

      Prend en charge le déploiement en un clic sur Function Compute (FC).oss-upload-post-signature-app

      Python

      import os
      from hashlib import sha1 as sha
      import json
      import base64
      import hmac
      import datetime
      import time
      
      # Configure the OSS_ACCESS_KEY_ID environment variable.
      access_key_id = os.environ.get('OSS_ACCESS_KEY_ID')
      # Configure the OSS_ACCESS_KEY_SECRET environment variable.
      access_key_secret = os.environ.get('OSS_ACCESS_KEY_SECRET')
      # Replace <YOUR_BUCKET> with your bucket name.
      bucket = '<YOUR_BUCKET>'
      # The host format is bucketname.endpoint. Replace <YOUR_BUCKET> with your bucket name. Replace <YOUR_ENDPOINT> with the OSS endpoint, such as oss-cn-hangzhou.aliyuncs.com.
      host = 'https://<YOUR_BUCKET>.<YOUR_ENDPOINT>'
      # Specify the prefix for files to upload to OSS.
      upload_dir = 'user-dir-prefix/'
      # Specify the expiration time in seconds.
      expire_time = 3600
      
      def generate_expiration(seconds):
          """
          Generate an expiration time by specifying a validity period in seconds.
          :param seconds: The validity period in seconds.
          :return: An ISO 8601 time string, such as "2014-12-01T12:00:00.000Z".
          """
          now = int(time.time())
          expiration_time = now + seconds
          gmt = datetime.datetime.utcfromtimestamp(expiration_time).isoformat()
          gmt += 'Z'
          return gmt
      
      def generate_signature(access_key_secret, expiration, conditions, policy_extra_props=None):
          """
          Generate a signature string.
          :param access_key_secret: The AccessKey secret of an account that has permissions to access the destination bucket.
          :param expiration: The signature expiration time, in ISO 8601 format and UTC. Example: "2014-12-01T12:00:00.000Z".
          :param conditions: Policy conditions used to limit the allowed values when uploading a form.
          :param policy_extra_props: Additional policy parameters. If new parameters are added to the policy, you can pass them as a dictionary.
          :return: signature, the signature string.
          """
          policy_dict = {
              'expiration': expiration,
              'conditions': conditions
          }
          if policy_extra_props is not None:
              policy_dict.update(policy_extra_props)
          policy = json.dumps(policy_dict).strip()
          policy_encode = base64.b64encode(policy.encode())
          h = hmac.new(access_key_secret.encode(), policy_encode, sha)
          sign_result = base64.b64encode(h.digest()).strip()
          return sign_result.decode()
      
      def generate_upload_params():
          policy = {
              # Validity period.
              "expiration": generate_expiration(expire_time),
              # Constraints.
              "conditions": [
                  # The status code to return after a successful upload if success_action_redirect is not specified. The default value is 204.
                  ["eq", "$success_action_status", "200"],
                  # The value of the form field must start with the specified prefix. For example, to specify that the value of key must start with user/user1, you can write ["starts-with", "$key", "user/user1"].
                  ["starts-with", "$key", upload_dir],
                  # Limit the minimum and maximum allowed size of the uploaded object in bytes.
                  ["content-length-range", 1, 1000000],
                  # Limit the uploaded file to specified image types.
                  ["in", "$content-type", ["image/jpg", "image/png"]]
              ]
          }
          signature = generate_signature(access_key_secret, policy.get('expiration'), policy.get('conditions'))
          response = {
              'policy': base64.b64encode(json.dumps(policy).encode('utf-8')).decode(),
              'ossAccessKeyId': access_key_id,
              'signature': signature,
              'host': host,
              'dir': upload_dir
              # You can add other parameters here.
          }
          return json.dumps(response)
      

      Java

      package com.aliyun.sample;
      
      import com.aliyun.oss.ClientException;
      import com.aliyun.oss.OSS;
      import com.aliyun.oss.OSSException;
      import com.aliyun.oss.common.utils.BinaryUtil;
      import com.aliyun.oss.model.MatchMode;
      import com.aliyun.oss.model.PolicyConditions;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      import org.codehaus.jettison.json.JSONObject;
      import java.util.Date;
      
      @Controller
      public class PostSignatureController {
          @Autowired
          private OSS ossClient;
      
          @Autowired
          private OssConfig ossConfig;
      
          @GetMapping("/get_post_signature_for_oss_upload")
          @ResponseBody
          public String generatePostSignature() {
              JSONObject response = new JSONObject();
              try {
                  long expireEndTime = System.currentTimeMillis() + ossConfig.getExpireTime() * 1000;
                  Date expiration = new Date(expireEndTime);
                  PolicyConditions policyConds = new PolicyConditions();
                  policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
                  policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, ossConfig.getDir());
                  String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
                  byte[] binaryData = postPolicy.getBytes("utf-8");
                  String encodedPolicy = BinaryUtil.toBase64String(binaryData);
                  String postSignature = ossClient.calculatePostSignature(postPolicy);
                  response.put("ossAccessKeyId", ossConfig.getAccessKeyId());
                  response.put("policy", encodedPolicy);
                  response.put("signature", postSignature);
                  response.put("dir", ossConfig.getDir());
                  response.put("host", ossConfig.getHost());
              } catch (OSSException oe) {
                  System.out.println("Caught an OSSException, which means your request made it to OSS, "
                          + "but was rejected with an error response for some reason.");
                  System.out.println("HTTP Status Code: " + oe.getRawResponseError());
                  System.out.println("Error Message: " + oe.getErrorMessage());
                  System.out.println("Error Code:       " + oe.getErrorCode());
                  System.out.println("Request ID:      " + oe.getRequestId());
                  System.out.println("Host ID:           " + oe.getHostId());
              } catch (ClientException ce) {
                  System.out.println("Caught an ClientException, which means the client encountered "
                          + "a serious internal problem while trying to communicate with OSS, "
                          + "such as not being able to access the network.");
                  System.out.println("Error Message: " + ce.getMessage());
              } catch (Exception e) {
                  System.out.println("Caught an unexpected exception: " + e.getMessage());
              }
              return response.toString();
          }
      }

      Go

      package main
      
      import (
      	"crypto/hmac"
      	"crypto/sha1"
      	"encoding/base64"
      	"encoding/json"
      	"fmt"
      	"io"
      	"net/http"
      	"os"
      	"time"
      )
      
      var (
      	// Configure the OSS_ACCESS_KEY_ID environment variable.
      	accessKeyId = os.Getenv("OSS_ACCESS_KEY_ID")
      	// Configure the OSS_ACCESS_KEY_SECRET environment variable.
      	accessKeySecret = os.Getenv("OSS_ACCESS_KEY_SECRET")
      	// The host format is bucketname.endpoint. Replace ${your-bucket} with your bucket name. Replace ${your-endpoint} with the OSS endpoint, such as oss-cn-hangzhou.aliyuncs.com.
      	host = "http://${your-bucket}.${your-endpoint}"
      	// Specify the prefix for files to upload to OSS.
      	uploadDir = "user-dir-prefix/"
      	// Specify the expiration time in seconds.
      	expireTime = int64(3600)
      )
      
      type ConfigStruct struct {
      	Expiration string          `json:"expiration"`
      	Conditions [][]interface{} `json:"conditions"`
      }
      
      type PolicyToken struct {
      	AccessKeyId string `json:"ossAccessKeyId"`
      	Host        string `json:"host"`
      	Signature   string `json:"signature"`
      	Policy      string `json:"policy"`
      	Directory   string `json:"dir"`
      }
      
      func getGMTISO8601(expireEnd int64) string {
      	return time.Unix(expireEnd, 0).UTC().Format("2006-01-02T15:04:05Z")
      }
      
      func getPolicyToken() string {
      	now := time.Now().Unix()
      	expireEnd := now + expireTime
      	tokenExpire := getGMTISO8601(expireEnd)
      
      	var config ConfigStruct
      	config.Expiration = tokenExpire
      
      	// Add a file prefix restriction.
      	config.Conditions = append(config.Conditions, []interface{}{"starts-with", "$key", uploadDir})
      
      	// Add a file size restriction, for example, from 1 KB to 10 MB.
      	minSize := int64(1024)
      	maxSize := int64(10 * 1024 * 1024)
      	config.Conditions = append(config.Conditions, []interface{}{"content-length-range", minSize, maxSize})
      
      	result, err := json.Marshal(config)
      	if err != nil {
      		fmt.Println("callback json err:", err)
      		return ""
      	}
      
      	encodedResult := base64.StdEncoding.EncodeToString(result)
      	h := hmac.New(sha1.New, []byte(accessKeySecret))
      	io.WriteString(h, encodedResult)
      	signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil))
      
      	policyToken := PolicyToken{
      		AccessKeyId: accessKeyId,
      		Host:        host,
      		Signature:   signedStr,
      		Policy:      encodedResult,
      		Directory:   uploadDir,
      	}
      
      	response, err := json.Marshal(policyToken)
      	if err != nil {
      		fmt.Println("json err:", err)
      		return ""
      	}
      
      	return string(response)
      }
      
      func handler(w http.ResponseWriter, r *http.Request) {
      	if r.URL.Path == "/" {
      		http.ServeFile(w, r, "templates/index.html")
      		return
      	} else if r.URL.Path == "/get_post_signature_for_oss_upload" {
      		policyToken := getPolicyToken()
      		w.Header().Set("Content-Type", "application/json")
      		w.Write([]byte(policyToken))
      		return
      	}
      	http.NotFound(w, r)
      }
      
      func main() {
      	http.HandleFunc("/", handler)
      	http.ListenAndServe(":8080", nil)
      }
      

      PHP

      <?php
      function gmt_iso8601($time)
      {
          return str_replace('+00:00', '.000Z', gmdate('c', $time));
      }
      
      // Obtain access credentials from environment variables. Before you run this sample code, make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are configured.
      $accessKeyId = getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
      $accessKeySecret = getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
      // The format of $host is '<YOUR-BUCKET>.<YOUR-ENDPOINT>'. Replace the variables with your actual information.
      $host = 'http://<YOUR-BUCKET>.<YOUR-ENDPOINT>';
      // The prefix specified by the user when uploading a file.
      $dir = 'user-dir-prefix/';          
      
      $now = time();
      // Set the policy to expire in 10 seconds. After this period, the policy becomes invalid.
      $expire = 30;  
      $end = $now + $expire;
      $expiration = gmt_iso8601($end);
      
      // Maximum file size. You can set this yourself.
      $condition = array(0 => 'content-length-range', 1 => 0, 2 => 1048576000);
      $conditions[] = $condition;
      
      // The uploaded data must start with $dir, otherwise the upload will fail. This step is not required but is recommended for security to prevent users from uploading to other directories through the policy.
      $start = array(0 => 'starts-with', 1 => '$key', 2 => $dir);
      $conditions[] = $start;
      
      $arr = array('expiration' => $expiration, 'conditions' => $conditions);
      $policy = json_encode($arr);
      $base64_policy = base64_encode($policy);
      $string_to_sign = $base64_policy;
      $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $accessKeySecret, true));
      
      $response = array();
      $response['ossAccessKeyId'] = $accessKeyId;
      $response['host'] = $host;
      $response['policy'] = $base64_policy;
      $response['signature'] = $signature;
      $response['dir'] = $dir;  
      echo json_encode($response);
      

      Node.js

      const express = require("express");
      const { Buffer } = require("buffer");
      const OSS = require("ali-oss");
      const app = express();
      const path = require("path");
      const config = {
        // Configure the ALIBABA_CLOUD_ACCESS_KEY_ID environment variable.
        accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
        // Configure the ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable.
        accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
        // Replace <YOUR-BUCKET> with your bucket name.
        bucket: "<YOUR-BUCKET>",
        // Specify the prefix for files to upload to OSS.
        dir: "prefix/",
      };
      
      app.use(express.static(path.join(__dirname, "templates")));
      
      app.get("/get_post_signature_for_oss_upload", async (req, res) => {
        const client = new OSS(config);
        const date = new Date();
        // Set the validity period of the signature in seconds.
        date.setSeconds(date.getSeconds() + 3600);
        const policy = {
          expiration: date.toISOString(),
          conditions: [
            // Set the size limit for the uploaded file.
            ["content-length-range", 0, 1048576000],
            // Restrict the bucket to which files can be uploaded.
            { bucket: client.options.bucket },
          ],
        };
        const formData = await client.calculatePostSignature(policy);
        const host = `http://${config.bucket}.${
          (await client.getBucketLocation()).location
        }.aliyuncs.com`.toString();
        const params = {
          policy: formData.policy,
          signature: formData.Signature,
          ossAccessKeyId: formData.OSSAccessKeyId,
          host,
          dir: config.dir,
        };
        res.json(params);
      });
      
      app.get(/^(.+)*\.(html|js)$/i, async (req, res) => {
        res.sendFile(path.join(__dirname, "./templates", req.originalUrl));
      });
      
      app.listen(8000, () => {
        console.log("http://127.0.0.1:8000");
      });
      

      Ruby

      require 'sinatra'
      require 'base64'
      require 'open-uri'
      require 'cgi'
      require 'openssl'
      require 'json'
      require 'sinatra/reloader'
      require 'sinatra/content_for'
      
      # Set the path of the public folder to the templates folder in the current directory.
      set :public_folder, File.dirname(__FILE__) + '/templates'
      
      # Configure the ALIBABA_CLOUD_ACCESS_KEY_ID environment variable.
      $access_key_id = ENV['ALIBABA_CLOUD_ACCESS_ID']
      # Configure the ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable.
      $access_key_secret = ENV['ALIBABA_CLOUD_ACCESS_SECRET']
      
      # The format of $host is <bucketname>.<endpoint>. Replace <bucketname> and <endpoint> with your actual information.
      $host = 'http://<bucketname>.<endpoint>';
      
      # The prefix for user-uploaded files.
      $upload_dir = 'user-dir-prefix/'
      # The expiration time in seconds.
      $expire_time = 30
      $server_ip = "0.0.0.0"
      $server_port = 8000
      
      if ARGV.length == 1 
        $server_port = ARGV[0]
      elsif ARGV.length == 2
        $server_ip = ARGV[0]
        $server_port = ARGV[1]
      end
      
      puts "App server is running on: http://#{$server_ip}:#{$server_port}"
      
      def hash_to_jason(source_hash)
        jason_string = source_hash.to_json;    
      
        jason_string.gsub!("\":[", "\": [")
        jason_string.gsub!("\",\"", "\", \"")
        jason_string.gsub!("],\"", "], \"")
        jason_string.gsub!("\":\"", "\": \"")
      
        jason_string
      end
      
      def get_token()
        expire_syncpoint = Time.now.to_i + $expire_time
        expire = Time.at(expire_syncpoint).utc.iso8601()
        response.headers['expire'] = expire
        policy_dict = {}
        condition_arrary = Array.new
        array_item = Array.new
        array_item.push('starts-with')
        array_item.push('$key')
        array_item.push($upload_dir)
        condition_arrary.push(array_item)
        policy_dict["conditions"] = condition_arrary
        policy_dict["expiration"] = expire
        policy = hash_to_jason(policy_dict)
        policy_encode = Base64.strict_encode64(policy).chomp;
        h = OpenSSL::HMAC.digest('sha1', $access_key_secret, policy_encode)
        hs = Digest::MD5.hexdigest(h)
        sign_result = Base64.strict_encode64(h).strip()
        token_dict = {}
        token_dict['ossAccessKeyId'] = $access_key_id
        token_dict['host'] = $host
        token_dict['policy'] = policy_encode
        token_dict['signature'] = sign_result 
        token_dict['expire'] = expire_syncpoint
        token_dict['dir'] = $upload_dir
        result = hash_to_jason(token_dict)
        result
      end
      
      set :bind, $server_ip
      set :port, $server_port
      
      get '/get_post_signature_for_oss_upload' do
        token = get_token()
        puts "Token: #{token}"
        token
      end
      
      get '/*' do
        puts "********************* GET "
        send_file File.join(settings.public_folder, 'index.html')
      end
      
      end
      
      if ARGV.length == 1 
        $server_port = ARGV[0]
      elsif ARGV.length == 2
        $server_ip = ARGV[0]
        $server_port = ARGV[1]
      end
      
      $server_ip = "0.0.0.0"
      $server_port = 8000
      
      puts "App server is running on: http://#{$server_ip}:#{$server_port}"
      
      set :bind, $server_ip
      set :port, $server_port
      
      get '/get_sts_token_for_oss_upload' do
        token = get_sts_token_for_oss_upload()
        response = {
          "AccessKeyId" => token["Credentials"]["AccessKeyId"],
          "AccessKeySecret" => token["Credentials"]["AccessKeySecret"],
          "SecurityToken" => token["Credentials"]["SecurityToken"]
        }
        response.to_json
      end
      
      get '/*' do
        puts "********************* GET "
        send_file File.join(settings.public_folder, 'index.html')
      end
      

      C#

      using Microsoft.AspNetCore.Builder;
      using Microsoft.Extensions.DependencyInjection;
      using Microsoft.AspNetCore.Http;
      using System.IO;
      using System.Collections.Generic;
      using System;
      using System.Globalization;
      using System.Text;
      using System.Security.Cryptography;
      using Newtonsoft.Json;
      using Microsoft.AspNetCore.Http.Extensions;
      using Microsoft.AspNetCore.Mvc;
      using Microsoft.Extensions.Logging;
      
      namespace YourNamespace
      {
          public class Program
          {
              private ILogger<Program> _logger;
              // Configure the ALIBABA_CLOUD_ACCESS_KEY_ID environment variable.
              public string AccessKeyId { get; set; } = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID");
              // Configure the ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable.
              public string AccessKeySecret { get; set; } = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
              // The host format is bucketname.endpoint. Replace <YOUR-BUCKET> with your bucket name. Replace <YOUR-ENDPOINT> with the OSS endpoint, such as oss-cn-hangzhou.aliyuncs.com.
              public string Host { get; set; } = "<YOUR-BUCKET>.<YOUR-ENDPOINT>";
              // Specify the prefix for files to upload to OSS.
              public string UploadDir { get; set; } = "user-dir-prefix/";
              // Specify the expiration time in seconds.
              public int ExpireTime { get; set; } = 3600;
              public class PolicyConfig
              {
                  public string expiration { get; set; }
                  public List<List<object>> conditions { get; set; }
              }
              public class PolicyToken
              {
                  public string Accessid { get; set; }
                  public string Policy { get; set; }
                  public string Signature { get; set; }
                  public string Dir { get; set; }
                  public string Host { get; set; }
                  public string Expire { get; set; }
              }
              public static void Main(string[] args)
              {
                  var builder = WebApplication.CreateBuilder(args);
                  var app = builder.Build();
      
                  builder.Logging.AddConsole();
                  var logger = builder.Services.BuildServiceProvider().GetRequiredService<ILogger<Program>>();
      
                  app.UseStaticFiles(); 
      
                  app.MapGet("/", async (context) =>
                  {
                      var filePath = Path.Combine(Directory.GetCurrentDirectory(), "templates/index.html");
                      var htmlContent = await File.ReadAllTextAsync(filePath);
                      await context.Response.WriteAsync(htmlContent);
                      logger.LogInformation("GET request to root path");
                  });
      
                  app.MapGet("/get_post_signature_for_oss_upload", async (context) =>
                  {
                      var program = new Program(logger);
                      var token = program.GetPolicyToken();
      
                      logger.LogInformation($"Token: {token}");
      
                      context.Response.ContentType = "application/json";
                      await context.Response.WriteAsync(token);
                  });
      
                  app.Run();
              }
      
              public Program(ILogger<Program> logger)
              {
                  _logger = logger;
              }
      
              private string ToUnixTime(DateTime dateTime)
              {
                  return ((DateTimeOffset)dateTime).ToUnixTimeSeconds().ToString();
              }
      
              private string GetPolicyToken()
              {
                  var expireDateTime = DateTime.Now.AddSeconds(ExpireTime);
                  var config = new PolicyConfig
                  {
                      expiration = FormatIso8601Date(expireDateTime),
                      conditions = new List<List<object>>()
                  };
                  config.conditions.Add(new List<object>
                  {
                      "content-length-range", 0, 1048576000
                  });
                  var policy = JsonConvert.SerializeObject(config);
                  var policyBase64 = EncodeBase64("utf-8", policy);
                  var signature = ComputeSignature(AccessKeySecret, policyBase64);
                  var policyToken = new PolicyToken
                  {
                      Accessid = AccessKeyId,
                      Host = Host,
                      Policy = policyBase64,
                      Signature = signature,
                      Expire = ToUnixTime(expireDateTime),
                      Dir = UploadDir
                  };
                  return JsonConvert.SerializeObject(policyToken);
              }
      
              private string FormatIso8601Date(DateTime dtime)
              {
                  return dtime.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'",
                                          CultureInfo.CurrentCulture);
              }
      
              private string EncodeBase64(string codeType, string code)
              {
                  string encode = "";
                  byte[] bytes = Encoding.GetEncoding(codeType).GetBytes(code);
                  try
                  {
                      encode = Convert.ToBase64String(bytes);
                  }
                  catch
                  {
                      encode = code;
                  }
                  return encode;
              }
      
              private string ComputeSignature(string key, string data)
              {
                  using (var algorithm = new HMACSHA1(Encoding.UTF8.GetBytes(key)))
                  {
                      return Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(data)));
                  }
              }
          }
      }
      
  2. Appelez l'opération PostObject avec la signature et la politique POST pour charger l'objet vers OSS à l'aide d'un formulaire HTML.

    Exemple JavaScript :

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Upload an object to OSS</title>
    </head>
    <body>
      <div class="container">
        <form>
          <div class="mb-3">
            <label for="file" class="form-label">Select the object</label>
            <input type="file" class="form-control" id="file" name="file" required>
          </div>
          <button type="submit" class="btn btn-primary">Upload</button>
        </form>
      </div>
      <script type="text/javascript">
          const form = document.querySelector('form');
          const fileInput = document.querySelector('#file');
          form.addEventListener('submit', (event) => {
            event.preventDefault();
            let file = fileInput.files[0];
            let filename = fileInput.files[0].name;
            fetch('/get_post_signature_for_oss_upload', { method: 'GET' })
              .then(response => response.json())
              .then(data => {
                const formData = new FormData();
                formData.append('name',filename);
                formData.append('policy', data.policy);
                formData.append('OSSAccessKeyId', data.ossAccessKeyId);
                formData.append('success_action_status', '200');
                formData.append('signature', data.signature);
                formData.append('key', data.dir + filename);
                // Set file to the last form field. No particular order is required for other form fields. 
                formData.append('file', file);
                fetch(data.host, { method: 'POST', body: formData},).then((res) => {
                  console.log(res);
                  alert ('Object Uploaded');
                });
              })
              .catch(error => {
                console.log('Error occurred while getting OSS upload parameters:', error);
              });
          });
      </script>
    </body>
    </html>
    

Remarques d'utilisation

Sécurité des données

Écrasement d'objets

Par défaut, OSS écrase les objets existants portant le même nom. Vous pouvez éviter les écrasements involontaires en utilisant les méthodes suivantes :

  • Activez le versioning pour le bucket

    Si le versioning est activé, les objets écrasés sont enregistrés en tant que versions précédentes que vous pouvez restaurer à tout moment. Pour plus d'informations, consultez Versioning.

  • Incluez le paramètre x-oss-forbid-overwrite dans la requête de chargement

    Ajoutez le paramètre x-oss-forbid-overwrite aux champs du formulaire et définissez-le sur true. Si un objet portant le même nom existe, le chargement échoue avec une erreur FileAlreadyExists. Si ce paramètre n'est pas inclus ou s'il est défini sur false, l'objet chargé écrase l'objet existant.

Chargement autorisé

Coûts des requêtes PUT

Si vous souhaitez charger un grand nombre d'objets, spécifier directement la classe de stockage Deep Cold Archive pour les objets à charger entraîne des frais de requête PUT élevés. Nous vous recommandons de spécifier d'abord la classe de stockage Standard pour les objets lors de leur chargement, puis d'utiliser des règles de cycle de vie pour les convertir vers la classe de stockage Deep Cold Archive afin de réduire les frais de requête PUT.

Buckets avec OSS-HDFS activé

Pour maintenir la stabilité d'OSS-HDFS et éviter toute perte de données, ne chargez pas d'objets dans le répertoire .dlsdata/ d'un bucket avec OSS-HDFS activé en utilisant des méthodes non prises en charge par OSS-HDFS.

Optimisation des performances de chargement

Si les noms d'objets contiennent des préfixes séquentiels tels que des horodatages et des lettres, plusieurs index peuvent être stockés dans une seule partition, ce qui augmente la latence des requêtes. Utilisez des préfixes aléatoires plutôt que des préfixes séquentiels lors du chargement de grands volumes d'objets. Pour plus d'informations, consultez Meilleures pratiques de performance OSS.