The same-origin policy is a security policy enforced on client-side web applications (like web browsers) to prevent interactions between resources from different origins. While useful for preventing malicious behavior, this security measure also prevents legitimate interactions between known origins. For example, a script on a page hosted at example.appspot.com might need to use resources stored in a Cloud Storage bucket at example.storage.googleapis.com. However, because these are two different origins from the perspective of the browser, the browser won't allow a script from example.appspot.com to fetch resources from example.storage.googleapis.com.
The Cross Origin Resource Sharing (CORS) spec was developed by the World Wide Web Consortium (W3C) to get around this limitation. Cloud Storage supports this specification by allowing you to configure your buckets to support CORS. Continuing the previous example, you can configure the example.storage.googleapis.com bucket so that a browser can share its resources with scripts from example.appspot.com.
For more information about CORS configuration components, see Set Bucket CORS.
How CORS works
There are two types of CORS requests: simple and preflighted. A simple request can be initiated directly. A preflighted request must send a preliminary, "preflight" request to the server to get permission before the primary request can proceed. A request is preflighted if any of the following circumstances are true:
- It uses methods other than GET,HEADorPOST.
- It uses the POSTmethod with aContent-Typeother thantext/plain,application/x-www-form-urlencoded, ormultipart/form-data.
- It sets custom headers. For example, X-PINGOTHER.
The following process occurs when a browser makes a simple request to Cloud Storage:
- The browser adds the - Originheader to the request. The- Originheader contains the origin of the resource seeking to share the Cloud Storage bucket's resources, for example,- Origin:https://www.example.appspot.com.
- Cloud Storage compares the HTTP method of the request and the value of the - Originheader to the Methods and Origins information in the target bucket's CORS configuration to see if there are matches. If there are, Cloud Storage includes the- Access-Control-Allow-Originheader in its response. The- Access-Control-Allow-Originheader contains the value of the- Originheader from the initial request.
- The browser receives the response and checks to see if the - Access-Control-Allow-Originvalue matches the domain specified in the original request. If they do match, the request succeeds. If they don't match, or if the- Access-Control-Allow-Originheader is not present in the response, the request fails.
A preflighted request performs the following steps first. If it is successful, it then follows the same process as a simple request:
- The browser sends an - OPTIONSrequest containing the- Requested Methodand- Requested Headersof the primary request.
- Cloud Storage responds back with the values of the HTTP methods and headers allowed by the targeted resource. If any of the method or header values in the preflight request aren't in the set of methods and headers allowed by the targeted resource, the request fails, and the primary request isn't sent. 
This is a simplified description of CORS. For a more complete description, read the Fetch spec.
Cloud Storage CORS support
Cloud Storage lets you set a CORS configuration at the bucket level only. You can set up a CORS configuration for a bucket using a variety of tools; however, different Cloud Storage endpoints deal with CORS requests in different ways:
- JSON API endpoints always allow CORS requests and return default values in the CORS response headers, regardless of the configuration set on the bucket. 
- XML API endpoints only allow CORS requests based on the configuration on the bucket and return specific CORS header values in response to that configuration. 
- The authenticated browser download endpoint - storage.cloud.google.comdoes not allow CORS requests. Note that the Google Cloud console provides this endpoint for each object's public URL link.
You can use either of the following XML API request URLs to obtain a response from Cloud Storage that contains the CORS headers:
storage.googleapis.com/BUCKET_NAME
BUCKET_NAME.storage.googleapis.com
For information about XML API request URLs, see Request Endpoints.
Components of a CORS configuration
When using the XML API, the values you set on your bucket's CORS configuration determine the CORS headers Cloud Storage returns in an HTTP response. When using the JSON API, Cloud Storage does not evaluate your bucket's configuration and instead returns default header values.
The following table describes the fields in a CORS configuration and the response behavior of the XML and JSON APIs. To learn how these fields are used, see CORS configuration examples.
| Field1 | Description | XML API response behavior | JSON API response behavior | 
|---|---|---|---|
| origin | Specify origins that you want to allow for cross origin resource sharing with this Cloud Storage bucket. For example, https://origin1.example.com. | If the origin in a browser's request matches an origin in your CORS configuration, Cloud Storage returns Access-Control-Allow-Originto the browser. If there is no match, Cloud Storage does not includeAccess-Control-Allow-Originin the response. You can supply a wildcard value that grants access to all origins:<Origin>*</Origin>. | Cloud Storage returns the Access-Control-Allow-Originheader set to the origin of the request. | 
| method | Specify HTTP methods that you want to allow for cross origin resource sharing with this Cloud Storage bucket. The value is returned in the  Since  | Cloud Storage supports the following methods:  Cloud Storage checks the methods sent from the browser in the  | Cloud Storage returns the Access-Control-Allow-Methodsheader set to the following methods:DELETE,GET,HEAD,PATCH,POST,PUT. | 
| responseHeader | Specify which headers you want to allow for cross origin resource sharing with this Cloud Storage bucket. The value is returned in the Access-Control-Allow-Headersheader in response to successful preflight requests. | For preflight requests, Cloud Storage checks the headers sent from the browser in the Access-Control-Request-Headersheader against the bucket's CORS configuration. If there is no match, Cloud Storage doesn't return CORS response headers. | Cloud Storage returns the Access-Control-Allow-Headersheader set equal to the values specified by theAccess-Control-Request-Headersheader. | 
| maxAgeSeconds(optional) | Specify the number of seconds the browser is allowed to make requests before it must repeat the preflight request. This is also known as the cache expiry time. This value is returned in the Access-Control-Max-Ageheader in responses to preflight requests. For example,3600sets the cache expiry time to 1 hour. | Cloud Storage returns the Access-Control-Max-Ageheader with the specified cache expiry time. If you omit this field, Cloud Storage returns the default value of3600. | Cloud Storage returns the Access-Control-Max-Ageheader with the default value of3600. | 
1 Names documented in the Field column are specific to the JSON API. When using the XML API to set a CORS configuration, use the XML-specific format.
Specifying multiple origins, methods, or headers
To learn how to set multiple origins, methods, or headers in a CORS configuration, see the following list:
- When using the JSON API, you can specify multiple origins, methods, or headers by using a comma-separated array. For example, - "method": ["GET", "PUT"].
- When using the XML API, you can specify multiple origins, methods, or headers by using separate elements. For example: - <Methods> <Method>PUT</Method> <Method>GET</Method> </Methods> 
- To allow requests to be made from any origin, set the origin to - *. For example,- "origin": ["*"]in the JSON API or- <Origin>*</Origin>in the XML API. While this origin is helpful for testing configurations, in most cases, you'll want to restrict request origins to prevent unwanted usage of your resources.
Additional considerations
The following table describes considerations when making requests using credentials or access control headers:
| Property or header | Description | XML API response behavior | JSON API response behavior | 
|---|---|---|---|
| Credentials | Cookies, authorization headers, or TLS client certificates. | Cloud Storage never returns the Access-Control-Allow-Credentialsheader. CORS credentials are not supported by the XML API. | For simple requests, if the CORS request is approved, the  For preflight requests, if  | 
| Exposed headers | For preflight requests, the Access-Control-Request-Headersrequest header indicates which headers a future CORS request might include. TheAccess-Control-Expose-Headersresponse header is included in the server's response and indicates to the client which headers can be exposed. | For simple requests, Access-Control-Expose-Headerslists the values of the response headers in your CORS configuration. | For simple requests, Access-Control-Expose-Headersreturns the values specified inAccess-Control-Request-Headersif they are part of a list of common HTTP headers. | 
Allowing buckets to access external resources
Sometimes, you might want to allow scripts hosted in Cloud Storage to access static resources that are hosted on a website external to Cloud Storage. In this scenario, the website serves CORS headers so that content on storage.googleapis.com is allowed access.
As a best practice, you should dedicate a specific bucket for this data access. This approach prevents your site from inadvertently over-exposing static resources to all of storage.googleapis.com. For example, if you want to dedicate a bucket named mybucket for data access, you should have the website serve the CORS header Access-Control-Allow-Origin: https://mybucket.storage.googleapis.com instead of Access-Control-Allow-Origin: https://storage.googleapis.com.
Client-side CORS support
Most browsers use the XMLHttpRequest object to make a cross-domain request. XMLHttpRequest takes care of all the work of inserting the right headers and handling the CORS interaction with the server. You don't have to add any new code to take advantage of CORS support on Cloud Storage buckets.
What's next
- Learn how to enable CORS for your bucket.
- Explore CORS configuration examples, including an example that removes the CORS configuration on a bucket.