[Overview](https://docs.cloud.google.com/storage/docs/cross-origin.md.txt)
[Setup](https://docs.cloud.google.com/storage/docs/using-cors.md.txt)

This page shows example configurations for
[Cross-origin resource sharing (CORS)](https://docs.cloud.google.com/storage/docs/cross-origin.md.txt).

When you set a CORS configuration on a bucket, you allow interactions
between resources from different origins, something that is normally prohibited
in order to prevent malicious behavior. To learn how to structure a request
that sets or edits a CORS configuration on a bucket, see the instructions in
[Using CORS](https://docs.cloud.google.com/storage/docs/using-cors.md.txt).

Note the following additional resources:

- For the generalized format of a CORS configuration file, see the
  [bucket resource representation for JSON](https://docs.cloud.google.com/storage/docs/json_api/v1/buckets.md.txt#resource-representations) or the
  [CORS configuration format for XML](https://docs.cloud.google.com/storage/docs/xml-api/put-bucket-metadata.md.txt#cors-body).

- When sending requests using the Google Cloud CLI, use the
  [correct CORS file configuration structure](https://docs.cloud.google.com/storage/docs/cors-configurations.md.txt#config-structure-gcloud).

## Basic CORS configuration

Say you have a dynamic website which users can
access at `your-example-website.appspot.com`. You have an image file hosted in a
Cloud Storage bucket named `your-example-bucket`. You'd like to use
the image on your website, so you must apply a CORS configuration on
`your-example-bucket` that enables your users' browsers to request resources
from the bucket. Based on the following configuration, preflight requests are
valid for 1 hour, and successful browser requests return the `Content-Type` of
the resource in the response.

> [!NOTE]
> **Note:** When [creating a CORS configuration](https://docs.cloud.google.com/storage/docs/using-cors.md.txt#configure-cors-bucket), you can [specify multiple origins, headers, and methods](https://docs.cloud.google.com/storage/docs/cross-origin.md.txt#multiple-origins-methods-headers).

### JSON API

```json
{
  "cors": [
    {
      "origin": ["https://your-example-website.appspot.com"],
      "method": ["GET"],
      "responseHeader": ["Content-Type"],
      "maxAgeSeconds": 3600
    }
  ]
}
```

### XML API

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CorsConfig>
  <Cors>
    <Origins>
      <Origin>https://your-example-website.appspot.com</Origin>
    </Origins>
    <Methods>
      <Method>GET</Method>
    </Methods>
    <ResponseHeaders>
      <ResponseHeader>Content-Type</ResponseHeader>
    </ResponseHeaders>
    <MaxAgeSec>3600</MaxAgeSec>
  </Cors>
</CorsConfig>
```

## Direct file uploads (for single-page applications)

Use this configuration when your frontend application needs to upload files
directly to a bucket, which requires a `PUT` operation. This is a common need
for single-page applications, where the application logic lives in the user's
browser instead of in a backend server.

Note that `PUT` requests always trigger a preflight check.

### JSON API

```json
{
 "cors": [
    {
        "origin": ["https://www.example-website.appspot.com"],
        "method": ["PUT", "POST", "OPTIONS"],
        "responseHeader": ["Content-Type", "x-goog-resumable"],
        "maxAgeSeconds": 3600
      }
  ]
}
```

### XML API

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CorsConfig>
  <Cors>
    <Origins>
      <Origin>https://your-example-website.appspot.com</Origin>
    </Origins>
    <Methods>
      <Method>PUT</Method>
      <Method>POST</Method>
      <Method>OPTIONS</Method>
    </Methods>
    <ResponseHeaders>
      <ResponseHeader>Content-Type</ResponseHeader>
      <ResponseHeader>x-goog-resumable</ResponseHeader>
    </ResponseHeaders>
    <MaxAgeSec>3600</MaxAgeSec>
  </Cors>
</CorsConfig>
```

### Client-side code sample

### JavaScript

```javascript
// Uploading a file using a Signed URL or direct PUT
await fetch(gcsSignedUrl, {
  method: 'PUT',
  body: fileBlob,
  headers: {
    'Content-Type': 'application/pdf'
  }
});
```

## Authenticated data access

Use this configuration if your application sends a bearer token or a
Google Identity header to access protected (non-public) objects.

### JSON API

```json
{
 "cors": [
    {
        "origin": ["https://www.example-secure-app.appspot.com"],
        "method": ["GET", "HEAD"],
        "responseHeader": ["Authorization", "Content-Type"],
        "maxAgeSeconds": 3600
      }
  ]
}
```

### XML API

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CorsConfig>
  <Cors>
    <Origins>
      <Origin>https://www.example-secure-app.appspot.com</Origin>
    </Origins>
    <Methods>
      <Method>GET</Method>
      <Method>HEAD</Method>
    </Methods>
    <ResponseHeaders>
      <ResponseHeader>Authorization</ResponseHeader>
      <ResponseHeader>Content-Type</ResponseHeader>
    </ResponseHeaders>
    <MaxAgeSec>3600</MaxAgeSec>
  </Cors>
</CorsConfig>
```

## Allowing access for multiple matching subdomains

Use this configuration if you have multiple development or staging environments
that need access to the same bucket. Using the wildcard `*` when specifying
a subdomain lets you match multiple subdomains. For example, `*.example.com`
can be used to match `test.example.com` and `prod.example.com`.

### JSON API

```json
{
 "cors": [
    {
        "origin": ["https://*.example.com"],
        "method": ["GET", "POST", "OPTIONS"],
        "responseHeader": ["Content-Type", "x-goog-resumable"],
        "maxAgeSeconds": 3600
      }
  ]
}
```

### XML API

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CorsConfig>
  <Cors>
    <Origins>
      <Origin>https://*.example.com</Origin>
    </Origins>
    <Methods>
      <Method>GET</Method>
      <Method>POST</Method>
      <Method>OPTIONS</Method>
    </Methods>
    <ResponseHeaders>
      <ResponseHeader>Content-Type</ResponseHeader>
      <ResponseHeader>x-goog-resumable</ResponseHeader>
    </ResponseHeaders>
    <MaxAgeSec>3600</MaxAgeSec>
  </Cors>
</CorsConfig>
```

## Allowing access for any origin

Use this configuration for public-facing data where restriction isn't required.
Specifying the wildcard `*` as the origin allows requests from any origin.
Note that with this configuration, requests to the bucket will fail if the
client sets `credentials: include` in their request.

### JSON API

```json
{
 "cors": [
    {
        "origin": ["*"],
        "method": ["GET"],
        "responseHeader": ["Content-Type"],
        "maxAgeSeconds": 1800
      }
  ]
}
```

### XML API

```xml
<?xml version="1.0" encoding="UTF-8"?>
<CorsConfig>
  <Cors>
    <Origins>
      <Origin>*</Origin>
    </Origins>
    <Methods>
      <Method>GET</Method>
    </Methods>
    <ResponseHeaders>
      <ResponseHeader>Content-Type</ResponseHeader>
    </ResponseHeaders>
    <MaxAgeSec>1800</MaxAgeSec>
  </Cors>
</CorsConfig>
```

## CORS configuration structure for gcloud CLI

The [`gcloud storage buckets update --cors-file`](https://docs.cloud.google.com/sdk/gcloud/reference/storage/buckets/update) command expects a file
containing only the list of CORS rules. When specifying a CORS configuration
to be [set](https://docs.cloud.google.com/storage/docs/using-cors.md.txt#configure-cors-bucket) using the Google Cloud CLI, remove the top level `"cors":`
wrapper from the JSON file.

For example, this gcloud CLI command sets a CORS configuration on
a bucket:

```
gcloud storage buckets update gs://example_bucket --cors-file=example_cors_file.json
```

This is an example configuration for `example_cors_file.json` that uses the
correct structure for the `gcloud storage buckets update --cors-file` command.

```json
[
    {
      "origin": ["https://your-example-website.appspot.com"],
      "method": ["GET"],
      "responseHeader": ["Content-Type"],
      "maxAgeSeconds": 3600
    }
]
```

## What's next

- Learn more about [Cross Origin Resource Sharing (CORS)](https://docs.cloud.google.com/storage/docs/cross-origin.md.txt).
- [Set and view the CORS configuration](https://docs.cloud.google.com/storage/docs/using-cors.md.txt) on a bucket.