Configura el uso compartido de recursos entre dominios (CORS)

Ir a los conceptos

El uso compartido de recursos entre dominios (CORS) permite interacciones entre recursos de diferentes orígenes, algo que por lo general está prohibido para evitar comportamientos maliciosos. Usa este tema para aprender a configurar CORS en un depósito de Cloud Storage.

Configura CORS en un depósito

Para establecer una configuración de CORS en un depósito, debes especificar cierta información, como los métodos HTTP y los dominios de origen, que identifique los tipos de solicitudes que aceptará. Puedes usar la herramienta de línea de comandos de gsutil, la API de XML, la API de JSON o las bibliotecas cliente de Cloud Storage a fin de establecer la configuración de CORS en un depósito.

En el siguiente ejemplo, se muestra cómo configurar el CORS en un depósito:

gsutil

  1. Crea un archivo JSON que contenga la siguiente información:

    [
        {
          "origin": ["[ORIGIN]"],
          "method": ["[METHOD]"],
          "responseHeader": ["[HEADER]"],
          "maxAgeSeconds": [MAX-AGE]
        }
    ]

    En el ejemplo anterior, se ilustra lo siguiente:

    • [ORIGIN] es un origen permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, example.appspot.com.
    • [METHOD] es un método HTTP permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, GET o PUT.
    • [HEADER] es un encabezado permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, Content-Type.
    • [MAX-AGE] es la cantidad de segundos que el navegador puede realizar solicitudes antes de que deba repetir la solicitud de comprobación previa. Por ejemplo, 3600.

    Para obtener más información, consulta Elementos de una configuración de CORS.

  2. Usa el comando gsutil cors para configurar CORS en un depósito:

    gsutil cors set [JSON_FILE_NAME].json gs://[BUCKET_NAME]

    En el ejemplo anterior, se ilustra lo siguiente:

    • [JSON_FILE_NAME] es la ruta de acceso al archivo JSON que creaste en el paso 1.
    • [BUCKET_NAME] es el nombre del depósito. Por ejemplo, my-bucket.

Muestras de código

C++

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para C++.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name,
   std::string const& origin) {
  StatusOr<gcs::BucketMetadata> original =
      client.GetBucketMetadata(bucket_name);

  if (!original) throw std::runtime_error(original.status().message());
  std::vector<gcs::CorsEntry> cors_configuration;
  cors_configuration.emplace_back(
      gcs::CorsEntry{3600, {"GET"}, {origin}, {"Content-Type"}});

  StatusOr<gcs::BucketMetadata> patched_metadata = client.PatchBucket(
      bucket_name,
      gcs::BucketMetadataPatchBuilder().SetCors(cors_configuration),
      gcs::IfMetagenerationMatch(original->metageneration()));

  if (!patched_metadata) {
    throw std::runtime_error(patched_metadata.status().message());
  }

  if (patched_metadata->cors().empty()) {
    std::cout << "Cors configuration is not set for bucket "
              << patched_metadata->name() << "\n";
    return;
  }

  std::cout << "Cors configuration successfully set for bucket "
            << patched_metadata->name() << "\nNew cors configuration: ";
  for (auto const& cors_entry : patched_metadata->cors()) {
    std::cout << "\n  " << cors_entry << "\n";
  }
}

Java

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Java.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Cors;
import com.google.cloud.storage.HttpMethod;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.common.collect.ImmutableList;

public class ConfigureBucketCors {
  public static void configureBucketCors(
      String projectId,
      String bucketName,
      String origin,
      String responseHeader,
      Integer maxAgeSeconds) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // The origin for this CORS config to allow requests from
    // String origin = "http://example.appspot.com";

    // The response header to share across origins
    // String responseHeader = "Content-Type";

    // The maximum amount of time the browser can make requests before it must repeat preflighted
    // requests
    // Integer maxAgeSeconds = 3600;

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Bucket bucket = storage.get(bucketName);

    // See the HttpMethod documentation for other HTTP methods available:
    // https://cloud.google.com/appengine/docs/standard/java/javadoc/com/google/appengine/api/urlfetch/HTTPMethod
    HttpMethod method = HttpMethod.GET;

    Cors cors =
        Cors.newBuilder()
            .setOrigins(ImmutableList.of(Cors.Origin.of(origin)))
            .setMethods(ImmutableList.of(method))
            .setResponseHeaders(ImmutableList.of(responseHeader))
            .setMaxAgeSeconds(maxAgeSeconds)
            .build();

    bucket.toBuilder().setCors(ImmutableList.of(cors)).build().update();

    System.out.println(
        "Bucket "
            + bucketName
            + " was updated with a CORS config to allow GET requests from "
            + origin
            + " sharing "
            + responseHeader
            + " responses across origins");
  }
}

C#

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para C#.

En este momento, no puedes configurar CORS con la biblioteca cliente de C #.

Go

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Go.

Si quieres establecer una configuración de CORS para un depósito mediante Go, consulta la documentación de referencia de CORS.

Node.js

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Node.js.

Si quieres establecer una configuración de CORS para un depósito mediante NodeJS, consulta la documentación de referencia de Depósito.

PHP

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para PHP.

Si quieres establecer una configuración de CORS para un depósito mediante PHP, consulta la documentación de referencia de Google\Cloud\Storage\Bucket.

Python

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Python.

Si quieres establecer una configuración de CORS para un depósito mediante Python, consulta la documentación de referencia de cors.

Ruby

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Ruby.

Si quieres establecer una configuración de CORS para un depósito mediante Ruby, consulta la documentación de referencia de Google::Cloud::Storage.

API de REST

API de JSON

  1. Obtén un token de autorización de acceso de OAuth 2.0 Playground. Configura Playground para usar tus credenciales de OAuth.
  2. Crea un archivo JSON que contenga la siguiente información:

    {
    "cors": [
      {
        "origin": [
          "[ORIGIN]"
        ],
        "method": [
          "[METHOD]"
        ],
        "responseHeader": [
          "[HEADER]"
        ],
        "maxAgeSeconds": [MAX-AGE]
      }
    ]
    }

    En el ejemplo anterior, se ilustra lo siguiente:

    • [ORIGIN] es un origen permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, example.appspot.com.
    • [METHOD] es un método HTTP permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, GET o PUT.
    • [HEADER] es un encabezado permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, Content-Type.
    • [MAX-AGE] es la cantidad de segundos que el navegador puede realizar solicitudes antes de que deba repetir la solicitud de comprobación previa. Por ejemplo, 3600.

    Para obtener más información, consulta Elementos de una configuración de CORS.

  3. Usa cURL para llamar a la API de JSON con una solicitud de depósito PATCH:

    curl --request PATCH \
    'https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]' \
    --header 'Authorization: Bearer [OAUTH2_TOKEN]' \
    --header 'Content-Type: application/json' \
    --data-binary @[JSON_FILE_NAME].json

    En el ejemplo anterior, se ilustra lo siguiente:

    • [BUCKET_NAME] es el nombre del depósito. Por ejemplo, my-bucket.
    • [OAUTH2_TOKEN] es el token de acceso que generaste en el paso 1.
    • [JSON_FILE_NAME] es la ruta de acceso al archivo que creaste en el paso 2.

API de XML

  1. Obtén un token de autorización de acceso de OAuth 2.0 Playground. Configura Playground para usar tus credenciales de OAuth.
  2. Crea un archivo XML que contenga la siguiente información:

    <?xml version="1.0" encoding="UTF-8"?>
    <CorsConfig>
    <Cors>
      <Origins>
        <Origin>[ORIGIN]</Origin>
      </Origins>
      <Methods>
        <Method>[METHOD]</Method>
      </Methods>
      <ResponseHeaders>
        <ResponseHeader>[HEADER]</ResponseHeader>
      </ResponseHeaders>
      <MaxAgeSec>[MAX-AGE]</MaxAgeSec>
    </Cors>
    </CorsConfig>
    

    En el ejemplo anterior, se ilustra lo siguiente:

    • [ORIGIN] es un origen permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, example.appspot.com.
    • [METHOD] es un método HTTP permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, GET o PUT.
    • [HEADER] es un encabezado permitido para el uso compartido de recursos entre dominios con este depósito. Por ejemplo, Content-Type.
    • [MAX-AGE] es la cantidad de segundos que el navegador puede realizar solicitudes antes de que deba repetir la solicitud de comprobación previa. Por ejemplo, 3600.

    Para obtener más información, consulta Elementos de una configuración de CORS.

  3. Usa cURL para llamar a la API de XML con una solicitud Set Bucket CORS:

    curl -X PUT --data-binary @[XML_FILE_NAME].xml \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "x-goog-project-id: [PROJECT_ID]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?cors"

    En el ejemplo anterior, se ilustra lo siguiente:

    • [BUCKET_NAME] es el nombre del depósito. Por ejemplo, my-bucket.
    • [OAUTH2_TOKEN] es el token de acceso que generaste en el paso 1.
    • [PROJECT_ID] es el ID del proyecto asociado con el depósito. Por ejemplo, my-project.
    • [XML_FILE_NAME] es la ruta de acceso al archivo que creaste en el paso 2.

Visualiza la configuración de CORS para un depósito

Para ver la configuración de CORS de un depósito, realiza las siguientes acciones:

gsutil

Usa el comando de gsutil cors para obtener la configuración de CORS de un depósito:

gsutil cors get gs://[BUCKET_NAME]

en el que [BUCKET_NAME] es el nombre del depósito. Por ejemplo, my-bucket.

Muestras de código

Si quieres ver la configuración de CORS de un depósito mediante las bibliotecas cliente, sigue las instrucciones para mostrar los metadatos de un depósito y busca el campo de CORS en la respuesta:

C++

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para C++.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name) {
  StatusOr<gcs::BucketMetadata> bucket_metadata =
      client.GetBucketMetadata(bucket_name);

  if (!bucket_metadata) {
    throw std::runtime_error(bucket_metadata.status().message());
  }

  std::cout << "The metadata for bucket " << bucket_metadata->name() << " is "
            << *bucket_metadata << "\n";
}

C#

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para C#.

private void GetBucketMetadata(string bucketName)
{
    var storage = StorageClient.Create();
    var bucket = storage.GetBucket(bucketName);
    Console.WriteLine($"Bucket:\t{bucket.Name}");
    Console.WriteLine($"Acl:\t{bucket.Acl}");
    Console.WriteLine($"Billing:\t{bucket.Billing}");
    Console.WriteLine($"Cors:\t{bucket.Cors}");
    Console.WriteLine($"DefaultEventBasedHold:\t{bucket.DefaultEventBasedHold}");
    Console.WriteLine($"DefaultObjectAcl:\t{bucket.DefaultObjectAcl}");
    Console.WriteLine($"Encryption:\t{bucket.Encryption}");
    if (bucket.Encryption != null)
    {
        Console.WriteLine($"KmsKeyName:\t{bucket.Encryption.DefaultKmsKeyName}");
    }
    Console.WriteLine($"Id:\t{bucket.Id}");
    Console.WriteLine($"Kind:\t{bucket.Kind}");
    Console.WriteLine($"Lifecycle:\t{bucket.Lifecycle}");
    Console.WriteLine($"Location:\t{bucket.Location}");
    Console.WriteLine($"LocationType:\t{bucket.LocationType}");
    Console.WriteLine($"Logging:\t{bucket.Logging}");
    Console.WriteLine($"Metageneration:\t{bucket.Metageneration}");
    Console.WriteLine($"Owner:\t{bucket.Owner}");
    Console.WriteLine($"ProjectNumber:\t{bucket.ProjectNumber}");
    Console.WriteLine($"RetentionPolicy:\t{bucket.RetentionPolicy}");
    Console.WriteLine($"SelfLink:\t{bucket.SelfLink}");
    Console.WriteLine($"StorageClass:\t{bucket.StorageClass}");
    Console.WriteLine($"TimeCreated:\t{bucket.TimeCreated}");
    Console.WriteLine($"Updated:\t{bucket.Updated}");
    Console.WriteLine($"Versioning:\t{bucket.Versioning}");
    Console.WriteLine($"Website:\t{bucket.Website}");
}

Go

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Go.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
)

// getBucketMetadata gets the bucket metadata.
func getBucketMetadata(w io.Writer, bucketName string) (*storage.BucketAttrs, error) {
	// bucketName := "bucket-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("storage.NewClient: %v", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()
	attrs, err := client.Bucket(bucketName).Attrs(ctx)
	if err != nil {
		return nil, fmt.Errorf("Bucket(%q).Attrs: %v", bucketName, err)
	}
	fmt.Fprintf(w, "BucketName: %v\n", attrs.Name)
	fmt.Fprintf(w, "Location: %v\n", attrs.Location)
	fmt.Fprintf(w, "LocationType: %v\n", attrs.LocationType)
	fmt.Fprintf(w, "StorageClass: %v\n", attrs.StorageClass)
	fmt.Fprintf(w, "TimeCreated: %v\n", attrs.Created)
	fmt.Fprintf(w, "Metageneration: %v\n", attrs.MetaGeneration)
	fmt.Fprintf(w, "PredefinedACL: %v\n", attrs.PredefinedACL)
	if attrs.Encryption != nil {
		fmt.Fprintf(w, "DefaultKmsKeyName: %v\n", attrs.Encryption.DefaultKMSKeyName)
	}
	if attrs.Website != nil {
		fmt.Fprintf(w, "IndexPage: %v\n", attrs.Website.MainPageSuffix)
		fmt.Fprintf(w, "NotFoundPage: %v\n", attrs.Website.NotFoundPage)
	}
	fmt.Fprintf(w, "DefaultEventBasedHold: %v\n", attrs.DefaultEventBasedHold)
	if attrs.RetentionPolicy != nil {
		fmt.Fprintf(w, "RetentionEffectiveTime: %v\n", attrs.RetentionPolicy.EffectiveTime)
		fmt.Fprintf(w, "RetentionPeriod: %v\n", attrs.RetentionPolicy.RetentionPeriod)
		fmt.Fprintf(w, "RetentionPolicyIsLocked: %v\n", attrs.RetentionPolicy.IsLocked)
	}
	fmt.Fprintf(w, "RequesterPays: %v\n", attrs.RequesterPays)
	fmt.Fprintf(w, "VersioningEnabled: %v\n", attrs.VersioningEnabled)
	if attrs.Logging != nil {
		fmt.Fprintf(w, "LogBucket: %v\n", attrs.Logging.LogBucket)
		fmt.Fprintf(w, "LogObjectPrefix: %v\n", attrs.Logging.LogObjectPrefix)
	}
	if attrs.Labels != nil {
		fmt.Fprintf(w, "\n\n\nLabels:")
		for key, value := range attrs.Labels {
			fmt.Fprintf(w, "\t%v = %v\n", key, value)
		}
	}
	return attrs, nil
}

Java

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Java.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.BucketInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.Map;

public class GetBucketMetadata {
  public static void getBucketMetadata(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

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

    // Select all fields. Fields can be selected individually e.g. Storage.BucketField.NAME
    Bucket bucket =
        storage.get(bucketName, Storage.BucketGetOption.fields(Storage.BucketField.values()));

    // Print bucket metadata
    System.out.println("BucketName: " + bucket.getName());
    System.out.println("DefaultEventBasedHold: " + bucket.getDefaultEventBasedHold());
    System.out.println("DefaultKmsKeyName: " + bucket.getDefaultKmsKeyName());
    System.out.println("Id: " + bucket.getGeneratedId());
    System.out.println("IndexPage: " + bucket.getIndexPage());
    System.out.println("Location: " + bucket.getLocation());
    System.out.println("LocationType: " + bucket.getLocationType());
    System.out.println("Metageneration: " + bucket.getMetageneration());
    System.out.println("NotFoundPage: " + bucket.getNotFoundPage());
    System.out.println("RetentionEffectiveTime: " + bucket.getRetentionEffectiveTime());
    System.out.println("RetentionPeriod: " + bucket.getRetentionPeriod());
    System.out.println("RetentionPolicyIsLocked: " + bucket.retentionPolicyIsLocked());
    System.out.println("RequesterPays: " + bucket.requesterPays());
    System.out.println("SelfLink: " + bucket.getSelfLink());
    System.out.println("StorageClass: " + bucket.getStorageClass().name());
    System.out.println("TimeCreated: " + bucket.getCreateTime());
    System.out.println("VersioningEnabled: " + bucket.versioningEnabled());
    if (bucket.getLabels() != null) {
      System.out.println("\n\n\nLabels:");
      for (Map.Entry<String, String> label : bucket.getLabels().entrySet()) {
        System.out.println(label.getKey() + "=" + label.getValue());
      }
    }
    if (bucket.getLifecycleRules() != null) {
      System.out.println("\n\n\nLifecycle Rules:");
      for (BucketInfo.LifecycleRule rule : bucket.getLifecycleRules()) {
        System.out.println(rule);
      }
    }
  }
}

Node.js

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Node.js.

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

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

async function getBucketMetadata() {
  // Get bucket metadata.
  /**
   * TODO(developer): Uncomment the following line before running the sample.
   */
  // const bucketName = 'Name of a bucket, e.g. my-bucket';

  // Get Bucket Metadata
  const [metadata] = await storage.bucket(bucketName).getMetadata();

  for (const [key, value] of Object.entries(metadata)) {
    console.log(`${key}: ${value}`);
  }
}

PHP

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para PHP.

use Google\Cloud\Storage\StorageClient;

/**
 * Get bucket metadata.
 *
 * @param string $bucketName the name of your Cloud Storage bucket.
 *
 * @return void
 */
function get_bucket_metadata($bucketName)
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);
    $info = $bucket->info();

    printf("Bucket Metadata: %s" . PHP_EOL, print_r($info));
}

Python

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Python.

import pprint

from google.cloud import storage

def bucket_metadata(bucket_name):
    """Prints out a bucket's metadata."""
    # bucket_name = 'your-bucket-name'

    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)

    print("ID: {}".format(bucket.id))
    print("Name: {}".format(bucket.name))
    print("Storage Class: {}".format(bucket.storage_class))
    print("Location: {}".format(bucket.location))
    print("Location Type: {}".format(bucket.location_type))
    print("Cors: {}".format(bucket.cors))
    print(
        "Default Event Based Hold: {}".format(bucket.default_event_based_hold)
    )
    print("Default KMS Key Name: {}".format(bucket.default_kms_key_name))
    print("Metageneration: {}".format(bucket.metageneration))
    print(
        "Retention Effective Time: {}".format(
            bucket.retention_policy_effective_time
        )
    )
    print("Retention Period: {}".format(bucket.retention_period))
    print("Retention Policy Locked: {}".format(bucket.retention_policy_locked))
    print("Requester Pays: {}".format(bucket.requester_pays))
    print("Self Link: {}".format(bucket.self_link))
    print("Time Created: {}".format(bucket.time_created))
    print("Versioning Enabled: {}".format(bucket.versioning_enabled))
    print("Labels:")
    pprint.pprint(bucket.labels)

Ruby

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage para Ruby.

# bucket_name = "Your Google Cloud Storage bucket name"

require "google/cloud/storage"

storage = Google::Cloud::Storage.new
bucket  = storage.bucket bucket_name

puts "ID:                       #{bucket.id}"
puts "Name:                     #{bucket.name}"
puts "Storage Class:            #{bucket.storage_class}"
puts "Location:                 #{bucket.location}"
puts "Location Type:            #{bucket.location_type}"
puts "Cors:                     #{bucket.cors}"
puts "Default Event Based Hold: #{bucket.default_event_based_hold?}"
puts "Default KMS Key Name:     #{bucket.default_kms_key}"
puts "Logging Bucket:           #{bucket.logging_bucket}"
puts "Logging Prefix:           #{bucket.logging_prefix}"
puts "Metageneration:           #{bucket.metageneration}"
puts "Retention Effective Time: #{bucket.retention_effective_at}"
puts "Retention Period:         #{bucket.retention_period}"
puts "Retention Policy Locked:  #{bucket.retention_policy_locked?}"
puts "Requester Pays:           #{bucket.requester_pays}"
puts "Self Link:                #{bucket.api_url}"
puts "Time Created:             #{bucket.created_at}"
puts "Versioning Enabled:       #{bucket.versioning?}"
puts "Index Page:               #{bucket.website_main}"
puts "Not Found Page:           #{bucket.website_404}"
puts "Labels:"
bucket.labels.each do |key, value|
  puts " - #{key} = #{value}"
end

API de REST

API de JSON

  1. Obtén un token de autorización de acceso de OAuth 2.0 Playground. Configura Playground para usar tus propias credenciales de OAuth.
  2. Usa cURL para llamar a la API de JSON con una solicitud de depósito GET:

    curl -X GET \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]?fields=cors"

    En el ejemplo anterior, se ilustra lo siguiente:

    • [OAUTH2_TOKEN] es el nombre del token de acceso que generaste en el paso 1.
    • [BUCKET_NAME] es el nombre del depósito correspondiente. Por ejemplo, my-bucket.

API de XML

  1. Obtén un token de autorización de acceso de OAuth 2.0 Playground. Configura Playground para usar tus propias credenciales de OAuth.
  2. Usa cURL para llamar a la API de XML con una solicitud de depósito GET:

    curl -X GET \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?cors"

    En el ejemplo anterior, se ilustra lo siguiente:

    • [OAUTH2_TOKEN] es el nombre del token de acceso que generaste en el paso 1.
    • [BUCKET_NAME] es el nombre del depósito correspondiente. Por ejemplo, my-bucket.

Quita CORS de un depósito

Para quitar la configuración de CORS de un depósito, realiza las siguientes acciones:

gsutil

  1. Crea un archivo JSON que contenga la siguiente información:

    []
  2. Usa el comando gsutil cors para configurar CORS en un depósito:

    gsutil cors set [JSON_FILE_NAME].json gs://[BUCKET_NAME]

    En el ejemplo anterior, se ilustra lo siguiente:

    • [JSON_FILE_NAME] es la ruta de acceso al archivo JSON que creaste en el paso 1.
    • [BUCKET_NAME] es el nombre del depósito. Por ejemplo, my-bucket.

API de REST

API de JSON

  1. Obtén un token de autorización de acceso de OAuth 2.0 Playground. Configura Playground para usar tus credenciales de OAuth.
  2. Crea un archivo JSON que contenga la siguiente información:

    {
    "cors": []
    }
  3. Usa cURL para llamar a la API de JSON con una solicitud de depósito PATCH:

    curl --request PATCH \
    'https://storage.googleapis.com/storage/v1/b/[BUCKET_NAME]' \
    --header 'Authorization: Bearer [OAUTH2_TOKEN]' \
    --header 'Content-Type: application/json' \
    --data-binary @[JSON_FILE_NAME].json

    En el ejemplo anterior, se ilustra lo siguiente:

    • [BUCKET_NAME] es el nombre del depósito. Por ejemplo, my-bucket.
    • [OAUTH2_TOKEN] es el token de acceso que generaste en el paso 1.
    • [JSON_FILE_NAME] es la ruta de acceso al archivo que creaste en el paso 2.

API de XML

  1. Obtén un token de autorización de acceso de OAuth 2.0 Playground. Configura Playground para usar tus credenciales de OAuth.
  2. Crea un archivo XML que contenga la siguiente información:

    <CorsConfig></CorsConfig>
  3. Usa cURL para llamar a la API de XML con una solicitud Set Bucket CORS:

    curl -X PUT --data-binary @[XML_FILE_NAME].xml \
    -H "Authorization: Bearer [OAUTH2_TOKEN]" \
    -H "x-goog-project-id: [PROJECT_ID]" \
    "https://storage.googleapis.com/[BUCKET_NAME]?cors"

    En el ejemplo anterior, se ilustra lo siguiente:

    • [BUCKET_NAME] es el nombre del depósito. Por ejemplo, my-bucket.
    • [OAUTH2_TOKEN] es el token de acceso que generaste en el paso 1.
    • [PROJECT_ID] es el ID del proyecto asociado con el depósito. Por ejemplo, my-project.
    • [XML_FILE_NAME] es la ruta de acceso al archivo que creaste en el paso 2.

Soluciona problemas de solicitudes de CORS

Si te encuentras con un comportamiento inesperado cuando accedes a los depósitos de Cloud Storage desde un origen diferente, prueba los siguientes pasos:

  1. Usa gsutil cors get en el depósito de destino para obtener su configuración de CORS. Si tienes varias entradas de configuración de CORS, asegúrate de que, a medida que avanzas por los siguientes pasos, los valores de solicitud se correspondan con los valores en la misma entrada de configuración de CORS individual.

  2. Comprueba que no estás realizando una solicitud al extremo storage.cloud.google.com, que no permite solicitudes de CORS. Para obtener más información sobre los extremos compatibles con CORS, consulta Compatibilidad con CORS de Cloud Storage.

  3. Revisa una solicitud y una respuesta mediante la herramienta que prefieras. En un navegador Chrome, puedes usar las herramientas para desarrolladores estándar a fin de ver esta información:

    1. Haz clic en el menú de Chrome Ícono de Menú de Chrome en la barra de herramientas del navegador.
    2. Selecciona Más herramientas > Herramientas para desarrolladores.
    3. Haz clic en la pestaña Red.
    4. Desde tu aplicación o la línea de comandos, envía la solicitud.
    5. En el panel que muestra la actividad de la red, busca la solicitud.
    6. En la columna Nombre, haz clic en el nombre correspondiente a la solicitud.
    7. Haz clic en la pestaña Encabezados para ver los encabezados de respuesta, o en la pestaña Respuesta si deseas ver el contenido de la respuesta.

    Si no ves una solicitud y respuesta, es posible que tu navegador tenga almacenado en caché un intento anterior de solicitud de verificación previa con errores. Si se borra la caché de tu navegador, también se debería borrar la caché de la comprobación previa. Si esto no sucede, configura el valor MaxAgeSec en tu configuración de CORS en un valor más bajo. Si no se especifica, el valor predeterminado es de 1,800 segundos (30 minutos). Espera el tiempo establecido en el MaxAgeSec anterior y, luego, intenta realizar la solicitud de nuevo. Esto realiza una nueva solicitud de comprobación previa, que recupera la configuración de CORS nueva y borra definitivamente las entradas de caché. Una vez que hayas depurado tu problema, vuelve a aumentar MaxAgeSec a un valor más alto, para reducir el tráfico de comprobación previa de tu depósito.

  4. Asegúrate de que la solicitud tenga un encabezado Origin y que el valor del encabezado coincida con al menos uno de los valores Origins en la configuración de CORS del depósito. Ten en cuenta que el esquema, el host y el puerto de los valores deben coincidir de forma exacta. Los siguientes son algunos ejemplos de coincidencias aceptables:

    • http://origin.example.com coincide con http://origin.example.com:80 (ya que 80 es el puerto HTTP predeterminado), pero no coincide con https://origin.example.com, http://origin.example.com:8080, http://origin.example.com:5151 ni http://sub.origin.example.com.

    • https://example.com:443 coincide con https://example.com pero no con http://example.com ni http://example.com:443.

    • http://localhost:8080 solo coincide de forma exacta con http://localhost:8080, no con http://localhost:5555 ni http://localhost.example.com:8080.

  5. Asegúrate de que el método HTTP de la solicitud (si es una solicitud simple) o el método especificado en Access-Control-Request-Method (si es una solicitud de comprobación previa) coincida con al menos uno de los valores Methods en la configuración de CORS del depósito.

  6. Si se trata de una solicitud de comprobación previa, verifica si incluye uno o más encabezados Access-Control-Request-Header. Si es así, asegúrate de que cada valor Access-Control-Request-Header coincida con un valor ResponseHeader en la configuración de CORS del depósito. Todos los encabezados nombrados en Access-Control-Request-Header deben estar en la configuración de CORS para que la solicitud de comprobación previa tenga éxito y se incluyan los encabezados de CORS en la respuesta.

Próximos pasos