Fazer o upload de um objeto com formulários HTML

Faz upload de objetos usando formulários HTML. O objeto enviado substitui qualquer objeto existente com o mesmo nome. Para obter dicas sobre como fazer o upload para o Cloud Storage, consulte as práticas recomendadas.

Para informações sobre solicitações de objeto POST usando o processo de assinatura legada, consulte Objeto POST com o processo de assinatura V2.

Parâmetros de string de consulta

Essa solicitação não inclui parâmetros de string de consulta.

Campos do formulário

Campo Descrição Obrigatório
acl A ACL predefinida que você quer aplicar ao objeto que está sendo enviado. Se você não especificar esse campo, a ACL default do intervalo será aplicada. Não
bucket O nome do bloco no qual você deseja fazer upload. Se você incluir esse campo, ele precisará corresponder ao nome do bucket especificado no atributo action. Não
Cache-Control O controle de cache para o objeto. Só é possível definir o controle de cache para um objeto acessível a todos os usuários. Por exemplo, a ACL de um objeto precisa ser public-read ou public-read-write para ser capaz de definir o controle de cache. Não
Content-Disposition Especifica como os dados do objeto devem ser transmitidos. Por exemplo, um valor Content-Disposition de inline significa que o objeto precisa ser exibido imediatamente. Não
Content-Encoding O algoritmo de compactação do objeto, como gzip. Não
Content-Length O tamanho do arquivo enviado, em bytes. Não
Content-Type O tipo MIME do arquivo que você está enviando por meio do formulário. Se você não especificar um tipo de conteúdo, o sistema do Cloud Storage usará como padrão application/octet-stream quando veicular o conteúdo. Não
Expires Um carimbo de data/hora ISO8601 que especifica a data e a hora antes de um objeto ser considerado obsoleto pelo navegador. Não
file O arquivo que você está enviando. Precisa ser o último campo do formulário. É possível fazer o upload de apenas um objeto por solicitação. Sim
key O nome do objeto que você está enviando. Também é possível usar a variável ${filename} se um usuário fornece um nome de arquivo. Sim
policy

A política de segurança que descreve o que pode e não pode ser enviado no formulário. O documento da política deve ser codificado em Base64. Consulte os documentos de política para mais informações.

*Se você não fornecer uma política de segurança, as solicitações serão consideradas anônimas e funcionarão apenas com buckets que receberam as permissões WRITE ou FULL_CONTROL para usuários anônimos.

Não*
success_action_redirect Um URL ao qual os usuários são redirecionados quando um upload é bem-sucedido. Se você não fornecer um URL, o Cloud Storage responderá com o código de status especificado em success_action_status. Não
success_action_status o código de status com que você quer que o Cloud Storage responda quando um upload for bem-sucedido. O padrão é 204, mas você pode alterar para 200 ou 201. Se você escolher 200 ou 204, o Cloud Storage retornará um documento vazio com esses códigos de status. Se você escolher 201, o Cloud Storage retornará um documento XML com os elementos descritos nos elementos do corpo da resposta. Observação: o Adobe Flash Player pode não processar respostas com um corpo de documento vazio. Use o código de status 201 se esse for o caso. Não
x-goog-algorithm O algoritmo de assinatura usado para criar a assinatura associada ao documento da política. Os valores possíveis são GOOG4-HMAC-SHA256 e GOOG4-RSA-SHA256. Somente se você especificar um policy
x-goog-credential As credenciais usadas para criar a assinatura associada ao documento da política. x-goog-credential tem a forma AccessKeyId/CredentialScope, em que:
  • AccessKeyId é o endereço de e-mail da entidade responsável pela criação da assinatura; Essa entidade costuma ser uma conta de serviço, mas também pode ser uma conta de usuário.
  • CredentialScope é o escopo da credencial usado na assinatura.
Somente se você especificar um policy
x-goog-custom-time Uma data e hora especificadas pelo usuário no formato RFC 3339 (em inglês) YYYY-MM-DD'T'HH:MM:SS.SS'Z'. Não
x-goog-date A data atual, no formato básico ISO 8601 YYYYMMDD'T'HHMMSS'Z'. Somente se você especificar um policy
x-goog-signature A assinatura associada ao documento da política. Somente se você especificar um policy
x-goog-meta-* Um campo para metadados personalizados. É possível usar isso para especificar outros metadados que não sejam fornecidos pelos outros campos do formulário. Por exemplo, x-goog-meta-reviewer: jane ou x-goog-meta-project-manager: john são metadados personalizados. Não

Elementos do corpo da resposta

Os seguintes elementos do corpo da resposta serão retornados em um documento XML somente se você definir success_action_status como 201.

Element Descrição
Bucket Bloco no qual o objeto foi armazenado.
ETag Tag da entidade HTTP 1.1 do objeto.
Key O nome do objeto.
Location O URI do objeto.

Uso e exemplos

O formulário precisa ser codificado em UTF-8. É possível especificar a codificação de formulário na tag head HTML do formulário ou usando o cabeçalho de solicitação Content-Type.

Sua tag form precisa especificar estes três itens:

  • Uma ação.

    O atributo action especifica um endpoint de solicitação da API XML. Os endpoints válidos incluem https://BUCKET_NAME.storage.googleapis.com, https://storage.googleapis.com/BUCKET_NAME e redirecionamentos CNAME.

  • Um método.

    O atributo method especifica o método que você está usando para enviar o formulário. Precisa ser post.

  • Um tipo de hiperlink anexo.

    O atributo enctype especifica o tipo de incorporação que você está usando e sempre precisa ser multipart/form-data.

Veja a seguir um exemplo de formulário HTML usando um documento de política:

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++

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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#

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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

Para mais informações, consulte a documentação de referência da API Cloud Storage para 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

Como prática recomendada, use o cabeçalho Expect: 100-continue com solicitações POST. Isso permite verificar se o servidor gerenciará a solicitação antes de enviar o objeto. Se você receber um código de status 100 Continue, prossiga com a solicitação. Se você receber um código de status 417 Expectation Failed, não envie o objeto.