Importer un objet avec des formulaires HTML

Permet d'importer des objets à l'aide de formulaires HTML. L'objet importé remplace tout objet existant portant le même nom. Pour obtenir des conseils sur l'importation dans Cloud Storage, consultez les bonnes pratiques.

Pour en savoir plus sur les requêtes d'objet POST à l'aide de l'ancien processus de signature, consultez la section Objet POST avec le processus de signature V2.

Paramètres de la chaîne de requête

Cette requête n'inclut pas les paramètres de chaîne de requête.

Champs de formulaire

Champ Description Requis
acl La LCA prédéfinie que vous souhaitez appliquer à l'objet en cours d'importation. Si vous ne spécifiez pas ce champ, la LCA default du bucket est appliquée. Non
bucket Nom du bucket dans lequel vous souhaitez importer les données. Si vous incluez ce champ, il doit correspondre au nom du bucket que vous spécifiez dans l'attribut action. Non
Cache-Control Contrôle du cache pour l'objet. Vous ne pouvez définir le contrôle du cache que pour un objet accessible à tous les utilisateurs. Par exemple, la LCA d'un objet doit être public-read ou public-read-write pour pouvoir définir le contrôle du cache. Non
Content-Disposition Spécifie comment les données de l'objet doivent être transmises. Par exemple, une valeur Content-Disposition de inline signifie que l'objet doit être affiché immédiatement. Non
Content-Encoding Algorithme de compression de l'objet, tel que gzip. Non
Content-Length Taille du fichier importé, en octets. Non
Content-Type Type MIME du fichier que vous importez via le formulaire. Si vous ne spécifiez pas de type de contenu, le système Cloud Storage utilise par défaut la valeur application/octet-stream lorsqu'il diffuse le contenu. Non
Expires Un horodatage ISO 8601 qui spécifie la date et l'heure avant qu'un objet soit considéré comme obsolète par le navigateur. Non
file Le fichier que vous importez. Il doit s'agir du dernier champ du formulaire. Vous ne pouvez importer qu'un seul objet par requête. Oui
key Nom de l'objet que vous importez. Vous pouvez également utiliser la variable ${filename} si un utilisateur fournit un nom de fichier. Oui
policy

La stratégie de sécurité qui décrit ce qui peut et ne peut pas être importé dans le formulaire. Le document de stratégie doit être encodé en base64. Pour en savoir plus, consultez les documents relatifs aux règles.

*Si vous ne fournissez pas de règles de sécurité, les requêtes sont considérées comme anonymes et ne fonctionnent qu'avec des buckets disposant de l'autorisation WRITE ou FULL_CONTROL.

Non*
success_action_redirect URL vers laquelle les utilisateurs sont redirigés lorsqu'une importation a réussi. Si vous ne fournissez pas d'URL, Cloud Storage répond avec le code d'état que vous avez spécifié dans success_action_status. Non
success_action_status Code d'état à partir duquel vous voulez que Cloud Storage répond lorsqu'une importation a réussi. La valeur par défaut est 204, mais vous pouvez la remplacer par 200 ou 201. Si vous choisissez 200 ou 204, Cloud Storage renvoie un document vide avec ces codes d'état. Si vous choisissez 201, Cloud Storage renvoie un document XML avec les éléments décrits dans la section "Éléments de corps de réponse". Remarque: Le lecteur Adobe Flash peut ne pas gérer les réponses si le corps du document est vide. Vous devez utiliser le code d'état 201 si c'est le cas. Non
x-goog-algorithm L'algorithme de signature utilisé pour créer la signature associée à votre document de stratégie. Les valeurs possibles sont GOOG4-HMAC-SHA256 et GOOG4-RSA-SHA256. Seulement si vous spécifiez un policy
x-goog-credential Les identifiants utilisés pour créer la signature associée à votre document de stratégie. x-goog-credential se présente sous la forme AccessKeyId/CredentialScope, où :
  • AccessKeyId est l'adresse e-mail de l'entité responsable de la création de la signature. Cette entité est généralement un compte de service, mais il peut également s'agir d'un compte utilisateur.
  • CredentialScope correspond au champ d'application des identifiants utilisé dans la signature.
Seulement si vous spécifiez un policy
x-goog-custom-time Date et heure définies par l'utilisateur au format RFC 3339 YYYY-MM-DD'T'HH:MM:SS.SS'Z'. Non
x-goog-date Date actuelle, au format de base ISO 8601 YYYYMMDD'T'HHMMSS'Z'. Seulement si vous spécifiez un policy
x-goog-signature La signature associée au document de stratégie. Seulement si vous spécifiez un policy
x-goog-meta-* Champ de métadonnées personnalisées. Vous pouvez utiliser cette option pour spécifier des métadonnées supplémentaires qui ne sont pas fournies par les autres champs de formulaire. Par exemple, x-goog-meta-reviewer: jane ou x-goog-meta-project-manager: john sont des métadonnées personnalisées. Non

Éléments du corps de la réponse

Les éléments de corps de réponse suivants ne sont renvoyés dans un document XML que si vous définissez success_action_status sur 201.

Élément Description
Bucket Bucket dans lequel l'objet a été stocké.
ETag Tag d'entité HTTP 1.1 pour l'objet.
Key Nom de l'objet.
Location URI de l'objet.

Utilisation et exemples

Le formulaire doit être encodé au format UTF-8. Vous pouvez spécifier l'encodage du formulaire dans la balise HTML head du formulaire ou à l'aide de l'en-tête de requête Content-Type.

Votre balise form doit spécifier les trois éléments suivants:

  • Une action.

    L'attribut action spécifie un point de terminaison de requête de l'API XML. Les points de terminaison valides incluent https://BUCKET_NAME.storage.googleapis.com, https://storage.googleapis.com/BUCKET_NAME et CNAME redirections.

  • Une méthode.

    L'attribut method spécifie la méthode que vous utilisez pour envoyer le formulaire. Il doit être post.

  • Type de boîtier.

    L'attribut enctype spécifie le type de boîtier utilisé et doit toujours être multipart/form-data.

Voici un exemple de formulaire HTML utilisant un document contenant des règles:

HTML

<form action="https://storage.googleapis.com/travel-maps" method="post" enctype="multipart/form-data">
<input type="text" name="key" value="test-object">
<input type="hidden" name="Content-Type" value="image/jpeg">
<input type="hidden" name="success_action_redirect" value="https://www.example.com/success_notification.html">
<input type="hidden" name="policy" value="eyJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJ0cmF2ZWwtbWFwcyJ9LHsiY29udGVudC10eXBlIjoiaW1hZ2UvanBlZyJ9LHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiJodHRwOi8vd3d3LmV4YW1wbGUuY29tL3N1Y2Nlc3Nfbm90aWZpY2F0aW9uLmh0bWwifSx7ImtleSI6InRlc3Qtb2JqZWN0In0seyJ4LWdvb2ctZGF0ZSI6IjIwMjAwMTIzVDA0MzUzMFoifSx7IngtZ29vZy1jcmVkZW50aWFsIjoiZXhhbXBsZV9hY2NvdW50QGV4YW1wbGVfcHJvamVjdC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbS8yMDE5MTEwMi9hdXRvL3N0b3JhZ2UvZ29vZzRfcmVxdWVzdCJ9LHsieC1nb29nLWFsZ29yaXRobSI6IkdPT0c0LVJTQS1TSEEyNTYifV0sImV4cGlyYXRpb24iOiIyMDIwLTAxLTIzVDA0OjM1OjQwWiJ9">
<input type="hidden" name="x-goog-algorithm" value="GOOG4-RSA-SHA256">
<input type="hidden" name="x-goog-credential" value="example_account@example_project.iam.gserviceaccount.com/20191102/auto/storage/goog4_request">
<input type="hidden" name="x-goog-date" value="20191102T043530Z">
<input type="hidden" name="x-goog-signature" value="58bc39b8f604ee1f18171fee4828ef8967f3d2721676570e115d68c2f133820cbb833976f18955516b2b7d0c3d9660fea613a2ad90c240bd02c1eefa4a55e9038ce74dcfdd34e278ea0436e261131a36fa4e922f0a077ca1c9842f654928aac3ca7f9341075f9db275d8286b5ef13e7f91b4837e77b2a6dbea83f86b90f848331053d8a6b1fbc26787992e7fb819a2005bae9b3026b9c7d1158e88e4a2018f13757083c7873241d2dfe6ea46a17cd6f3d090f3e0da44ccfbd6bc425124de1bea744a32f3ab175672a991ef274cd83550eca57ea591b85fa9799098a38ec552dc3ec679c431491444820624f5c4ba0c8cf87d60af89899afce2a90325c6966dcf">

<input name="file" type="file">
<input type="submit" value="Upload">
</form>

C++

C++

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage C++.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name,
   std::string const& object_name, std::string const& signing_account) {
  auto document = client.GenerateSignedPostPolicyV4(
      gcs::PolicyDocumentV4{
          bucket_name,
          object_name,
          /*expiration=*/std::chrono::minutes(10),
      },
      gcs::AddExtensionFieldOption("x-goog-meta-test", "data"),
      gcs::SigningAccount(signing_account));
  if (!document) throw std::runtime_error(document.status().message());

  // Create the HTML form for the computed policy.
  std::ostringstream os;
  os << "<form action='" << document->url << "' method='POST'"
     << " enctype='multipart/form-data'>\n";
  for (auto const& field : document->required_form_fields) {
    os << "  <input name='" << field.first << "' value='" << field.second
       << "' type='hidden' />\n";
  }
  os << "  <input type='submit' value='Upload File' /><br />\n"
     << "  <input type='file' name='file' /><br />\n"
     << "</form>";

  std::cout << "A sample HTML form:\n" << os.str() << "\n";
}

C#

C#

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage C#.

// Create a signed post policy which can be used to upload a specific object and
// expires in 1 hour after creation.
UrlSigner urlSigner = UrlSigner
    .FromServiceAccountCredential(credential);
UrlSigner.Options options = UrlSigner.Options
    .FromDuration(TimeSpan.FromHours(1))
    .WithSigningVersion(SigningVersion.V4)
    .WithScheme("https");
UrlSigner.PostPolicy postPolicy = UrlSigner.PostPolicy.ForBucketAndKey(bucketName, objectName);
postPolicy.SetCustomField(UrlSigner.PostPolicyCustomElement.GoogleMetadata, "x-goog-meta-test", "data");

UrlSigner.SignedPostPolicy signedPostPolicy = await urlSigner.SignAsync(postPolicy, options);

// Create an HTML form including all the fields in the signed post policy.
StringBuilder form = new StringBuilder();
form.AppendLine($"<form action=\"{signedPostPolicy.PostUrl}\" method=\"post\" enctype=\"multipart/form-data\">");
foreach (var field in signedPostPolicy.Fields)
{
    form.AppendLine($"<input type=\"hidden\" name=\"{field.Key}\" value=\"{field.Value}\">");
}
// Include the file element. It should always be the last element in the form.
form.AppendLine("<input name=\"file\" type=\"file\">");
form.AppendLine("<input type=\"submit\" value=\"Upload\">");
form.AppendLine("</form>");

// You can now save the form to file and serve it as static content
// or send it as the response to a request made to your application.
File.WriteAllText("PostPolicySimple.html", form.ToString());

Java

Java

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Java.

import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.PostPolicyV4;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class GenerateSignedPostPolicyV4 {
  /**
   * Generating a signed POST policy requires Credentials which implement ServiceAccountSigner.
   * These can be set explicitly using the Storage.PostPolicyV4Option.signWith(ServiceAccountSigner)
   * option. If you don't, you could also pass a service account signer to StorageOptions, i.e.
   * StorageOptions().newBuilder().setCredentials(ServiceAccountSignerCredentials). In this example,
   * neither of these options are used, which means the following code only works when the
   * credentials are defined via the environment variable GOOGLE_APPLICATION_CREDENTIALS, and those
   * credentials are authorized to sign a policy. See the documentation for
   * Storage.generateSignedPostPolicyV4 for more details.
   */
  public static void generateSignedPostPolicyV4(
      String projectId, String bucketName, String blobName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of the GCS bucket to upload to
    // String bucketName = "your-bucket-name"

    // The name to give the object uploaded to GCS
    // String blobName = "your-object-name"

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();

    PostPolicyV4.PostFieldsV4 fields =
        PostPolicyV4.PostFieldsV4.newBuilder().AddCustomMetadataField("test", "data").build();

    PostPolicyV4 policy =
        storage.generateSignedPostPolicyV4(
            BlobInfo.newBuilder(bucketName, blobName).build(), 10, TimeUnit.MINUTES, fields);

    StringBuilder htmlForm =
        new StringBuilder(
            "<form action='"
                + policy.getUrl()
                + "' method='POST' enctype='multipart/form-data'>\n");
    for (Map.Entry<String, String> entry : policy.getFields().entrySet()) {
      htmlForm.append(
          "  <input name='"
              + entry.getKey()
              + "' value='"
              + entry.getValue()
              + "' type='hidden' />\n");
    }
    htmlForm.append("  <input type='file' name='file'/><br />\n");
    htmlForm.append("  <input type='submit' value='Upload File'/><br />\n");
    htmlForm.append("</form>\n");

    System.out.println(
        "You can use the following HTML form to upload an object to bucket "
            + bucketName
            + " for the next ten minutes:");
    System.out.println(htmlForm.toString());
  }
}

Go

Go

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Go.

import (
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"time"

	"cloud.google.com/go/storage"
	"golang.org/x/oauth2/google"
)

// form is a template for an HTML form that will use the data from the signed
// post policy.
var form = `<form action="{{ .URL }}" method="POST" enctype="multipart/form-data">
	{{- range $name, $value := .Fields }}
	<input name="{{ $name }}" value="{{ $value }}" type="hidden"/>
	{{- end }}
	<input type="file" name="file"/><br />
	<input type="submit" value="Upload File" name="submit"/><br />
</form>`

var tmpl = template.Must(template.New("policyV4").Parse(form))

// generateSignedPostPolicyV4 generates a signed post policy.
func generateSignedPostPolicyV4(w io.Writer, bucket, object, serviceAccountJSONPath string) (*storage.PostPolicyV4, error) {
	// bucket := "bucket-name"
	// object := "object-name"
	// serviceAccountJSONPath := "service_account.json"
	jsonKey, err := ioutil.ReadFile(serviceAccountJSONPath)
	if err != nil {
		return nil, fmt.Errorf("ioutil.ReadFile: %v", err)
	}
	conf, err := google.JWTConfigFromJSON(jsonKey)
	if err != nil {
		return nil, fmt.Errorf("google.JWTConfigFromJSON: %v", err)
	}
	metadata := map[string]string{
		"x-goog-meta-test": "data",
	}
	opts := &storage.PostPolicyV4Options{
		GoogleAccessID: conf.Email,
		PrivateKey:     conf.PrivateKey,
		Expires:        time.Now().Add(10 * time.Minute),
		Fields: &storage.PolicyV4Fields{
			Metadata: metadata,
		},
	}

	policy, err := storage.GenerateSignedPostPolicyV4(bucket, object, opts)
	if err != nil {
		return nil, fmt.Errorf("storage.GenerateSignedPostPolicyV4: %v", err)
	}

	// Generate the form, using the data from the policy.
	if err = tmpl.Execute(w, policy); err != nil {
		return policy, fmt.Errorf("executing template: %v", err)
	}

	return policy, nil
}

Node.js

Node.js

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Node.js.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of your GCS file
// const fileName = 'your-file-name';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function generateV4SignedPolicy() {
  const bucket = storage.bucket(bucketName);
  const file = bucket.file(fileName);

  // These options will allow temporary uploading of a file
  // through an HTML form.
  const expires = Date.now() + 10 * 60 * 1000; //  10 minutes
  const options = {
    expires,
    fields: {'x-goog-meta-test': 'data'},
  };

  // Get a v4 signed policy for uploading file
  const [response] = await file.generateSignedPostPolicyV4(options);

  // Create an HTML form with the provided policy
  let output = `<form action='${response.url}' method='POST' enctype="multipart/form-data">\n`;
  // Include all fields returned in the HTML form as they're required
  for (const name of Object.keys(response.fields)) {
    const value = response.fields[name];
    output += `  <input name='${name}' value='${value}' type='hidden'/>\n`;
  }
  output += "  <input type='file' name='file'/><br />\n";
  output +=
    "  <input type='submit' value='Upload File' name='submit'/><br />\n";
  output += '</form>';

  console.log(output);
}

generateV4SignedPolicy().catch(console.error);

PHP

PHP

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage PHP.

use Google\Cloud\Storage\StorageClient;

/**
 * Generates a V4 POST Policy to be used in an HTML form and echo's form.
 *
 * @param string $bucketName the name of your Google Cloud bucket.
 * @param string $objectName the name of your Google Cloud object.
 *
 * @return void
 */
function generate_v4_post_policy($bucketName, $objectName)
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);

    $response = $bucket->generateSignedPostPolicyV4(
        $objectName,
        new \DateTime('10 min'),
        [
            'fields' => [
                'x-goog-meta-test' => 'data'
            ]
        ]
    );

    $url = $response['url'];
    $output = "<form action='$url' method='POST' enctype='multipart/form-data'>" . PHP_EOL;
    foreach ($response['fields'] as $name => $value) {
        $output .= "  <input name='$name' value='$value' type='hidden'/>" . PHP_EOL;
    }
    $output .= "  <input type='file' name='file'/><br />" . PHP_EOL;
    $output .= "  <input type='submit' value='Upload File' name='submit'/><br />" . PHP_EOL;
    $output .= "</form>" . PHP_EOL;

    echo $output;
}

Python

Python

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Python.

import datetime

from google.cloud import storage

def generate_signed_post_policy_v4(bucket_name, blob_name):
    """Generates a v4 POST Policy and prints an HTML form."""
    # bucket_name = 'your-bucket-name'
    # blob_name = 'your-object-name'

    storage_client = storage.Client()

    policy = storage_client.generate_signed_post_policy_v4(
        bucket_name,
        blob_name,
        expiration=datetime.timedelta(minutes=10),
        fields={
          'x-goog-meta-test': 'data'
        }
    )

    # Create an HTML form with the provided policy
    header = "<form action='{}' method='POST' enctype='multipart/form-data'>\n"
    form = header.format(policy["url"])

    # Include all fields returned in the HTML form as they're required
    for key, value in policy["fields"].items():
        form += "  <input name='{}' value='{}' type='hidden'/>\n".format(key, value)

    form += "  <input type='file' name='file'/><br />\n"
    form += "  <input type='submit' value='Upload File' /><br />\n"
    form += "</form>"

    print(form)

    return form

Ruby

Ruby

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Ruby.

def generate_signed_post_policy_v4 bucket_name:, file_name:
  # The ID of the GCS bucket to upload to
  # bucket_name = "your-unique-bucket-name"

  # The name to give the object uploaded to GCS
  # file_name = "your-file-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new

  bucket = storage.bucket bucket_name
  post_object = bucket.generate_signed_post_policy_v4 file_name,
                                                      expires: 600,
                                                      fields:  { "x-goog-meta-test" => "data" }

  html_form = "<form action='#{post_object.url}' method='POST' enctype='multipart/form-data'>\n"
  post_object.fields.each do |name, value|
    html_form += "  <input name='#{name}' value='#{value}' type='hidden'/>\n"
  end
  html_form += "  <input type='file' name='file'/><br />\n"
  html_form += "  <input type='submit' value='Upload File'/><br />\n"
  html_form += "</form>\n"

  puts "You can use the following form to upload an object to bucket #{bucket_name} for the next 10 minutes:\n"
  puts html_form

  post_object
end

Il est recommandé d'utiliser l'en-tête Expect: 100-continue avec les requêtes POST. Cela vous permet de vérifier que le serveur traitera la requête avant d'envoyer l'objet. Si vous recevez un code d'état 100 Continue, poursuivez la demande. Si vous recevez un code d'état 417 Expectation Failed, vous ne devez pas envoyer l'objet.