Cross-origin resource sharing (CORS) is a standard cross-origin solution provided by HTML5 to allow web application servers to control cross-origin access. This way, the security of data transmission across origins is ensured.

Same-origin check

Browsers reject cross-origin requests based on the same-origin policy to keep website content secure. When a request is sent from Website A by using the JavaScript code to access Website B of another origin, the browser rejects the request. In this case, you can configure CORS rules to allow cross-origin requests.

Origins that use the same protocol, domain name or IP address, and port number are considered the same origin. The following table lists examples and checks whether the examples and http://www.aliyun.com/org/test.html are from the same origin.
URL Successful access Cause
http://www.aliyun.com/org/other.html Yes Same protocol, domain name, and port number
http://www.aliyun.com/org/internal/page.html Yes Same protocol, domain name, and port number
https://www.aliyun.com/page.html No Different protocols (HTTP and HTTPS)
http://www.aliyun.com:22/dir/page.html No Different port numbers (port 22 and no port number)
http://www.alibabacloud.com/help/other.html No Different domain names

The preceding table shows that the browser rejects requests from the origins whose protocols, domain names, or port numbers are different from those of the accessed origin. If you want to allow access from these origins, you must configure CORS rules.

Precautions

  • You can configure up to 10 CORS rules for a bucket.
  • When OSS receives a cross-origin request or an OPTIONS request that is destined for a bucket, OSS reads the CORS rules that are configured for the bucket and attempts to match the rules one after another. If OSS finds the first match, OSS returns corresponding headers. If the request fails to match the CORS rules, OSS does not include CORS headers in the response.
  • To implement CORS after Alibaba Cloud CDN is activated, you must configure CORS rules in the CDN console. For more information, see Configure CORS for Alibaba Cloud CDN.

CORS rules

You can configure CORS rules to allow or reject cross-origin requests based on your requirements. CORS rules are configured only to determine whether to add CORS-related headers to requests. The browser determines whether to reject cross-origin requests.

If one of the following conditions is met, you must select Vary: Origin to avoid local cache errors.
Notice If Vary: Origin is selected, visits through the browser or the CDN back-to-origin requests may increase.
  • CORS and non-CORS requests are sent at the same time

    For example, in the following code, a non-CORS request is created in the <img> field and a CORS request is created by using the fetch method:

    <!doctype html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>CORS Test</title>
    </head>
    <body>
    // Create a non-CORS request. 
    <img src="https://examplebucket.oss-cn-beijing.aliyuncs.com/exampleobject.txt" alt="">
    <script>
      // Create a CORS request. 
      fetch("https://examplebucket.oss-cn-beijing.aliyuncs.com/exampleobject.txt").then(console.log)
    </script>
    </body>
    </html>
  • The Origin header has multiple possible values

    For example, you can set the Origin header to http://www.example.com and https://www.example.org to allow CORS requests from these origins.

Use the OSS console

  1. Log on to the OSS console.
  2. In the left-side navigation pane, click Buckets. On the Buckets page, click the name of the bucket that you want to manage.
  3. In the left-side navigation pane, choose Access Control > Cross-Origin Resource Sharing (CORS). In the Cross-Origin Resource Sharing (CORS) section, click Configure.
  4. Click Create Rule. In the Create Rule panel, configure the parameters. The following table describes the parameters.
    Parameter Required Description
    Sources Yes The sources from which you want to allow cross-origin requests. When you configure the sources, take note of the following rules:
    • You can configure multiple sources. Separate multiple sources with line feeds.
    • The domain names must include the protocol name, such as HTTP or HTTPS.
    • You can use the asterisk (*) as a wildcard character. Each source can contain up to one asterisk (*).
    • If a domain name does not use the default port, the domain name must contain the port number. Example: https://www.example.com:8080.
    The following examples show how to configure domain names:
    • To match a specified domain name, enter the full domain name. Example: https://www.example.com.
    • To match second-level domain names, use an asterisk (*) as the wildcard character in the domain name. Example: https://*.example.com.
    • To match all domain names, enter only an asterisk (*) as the wildcard character.
    Allowed Methods Yes The methods that cross-origin requests are allowed to use.
    Allowed Headers No The response headers for the allowed cross-origin requests. When you configure the headers, take note of the following rules:
    • This parameter is in the key:value format and not case-sensitive. Example: content-type:text/plain.
    • You can configure multiple response headers. Separate multiple response headers with line feeds.
    • Each response header can have only one asterisk (*) as the wildcard character. Set this parameter to an asterisk (*) if you do not have special requirements.
    Exposed Headers No The response headers for allowed access requests from applications, such as an XMLHttpRequest object in JavaScript. Exposed headers cannot contain asterisks (*).
    Cache Timeout (Seconds) No The period of time in which the browser can cache the response to an OPTIONS preflight request for specific resources. Unit: seconds.
    Vary: Origin No Specifies whether to return the Vary: Origin header.

    If both CORS and non-CORS requests are sent at the same time, or if the Origin header has multiple possible values, we recommend that you select the Vary: Origin header to avoid errors in the local cache.

    Notice If Vary: Origin is selected, visits through the browser or the CDN back-to-origin requests may increase.

    For more information about the parameters, see PutBucketCors.

  5. Click OK.

Use OSS SDKs

The following code provides examples on how to use OSS SDKs for common programming languages to configure CORS rules. For more information about the sample code for other programming languages, see Overview.

// Set endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
// Specify the name of the bucket. Example: examplebucket. 
String bucketName = "examplebucket";

// Create an OSSClient instance. 
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

SetBucketCORSRequest request = new SetBucketCORSRequest(bucketName);

// Create a container for the CORS rules. You can configure up to 10 CORS rules for each bucket. 
ArrayList<SetBucketCORSRequest.CORSRule> putCorsRules = new ArrayList<SetBucketCORSRequest.CORSRule>();

SetBucketCORSRequest.CORSRule corRule = new SetBucketCORSRequest.CORSRule();

ArrayList<String> allowedOrigin = new ArrayList<String>();
// Specify the origins from which cross-origin requests are allowed. 
allowedOrigin.add( "http://example.com");

ArrayList<String> allowedMethod = new ArrayList<String>();
// Specify the HTTP methods that cross-origin requests are allowed to use, including PUT, POST, GET, DELETE, and HEAD. 
allowedMethod.add("GET");

ArrayList<String> allowedHeader = new ArrayList<String>();
// Specify whether the headers that are specified by Access-Control-Request-Headers in the OPTIONS preflight request are allowed. 
allowedHeader.add("x-oss-test");

ArrayList<String> exposedHeader = new ArrayList<String>();
// Specify the response headers for allowed access requests from applications. 
exposedHeader.add("x-oss-test1");
// You can use only one asterisk (*) as the wildcard character for AllowedOrigins and AllowedMethods in a CORS rule. The asterisk (*) wildcard character specifies that all origins or operations are allowed. 
corRule.setAllowedMethods(allowedMethod);
corRule.setAllowedOrigins(allowedOrigin);
// AllowedHeaders and ExposeHeaders do not support wildcard characters. 
corRule.setAllowedHeaders(allowedHeader);
corRule.setExposeHeaders(exposedHeader);
// Specify the period of time in which the browser can cache the response to an OPTIONS preflight request for specific resources. Unit: seconds. 
corRule.setMaxAgeSeconds(10);

// You can configure up to 10 CORS rules for the bucket. 
putCorsRules.add(corRule);
// The existing rules are overwritten. 
request.setCorsRules(putCorsRules);
// Specify whether to return the Vary: Origin header. If you set this parameter to TRUE, the Vary: Origin header is returned regardless of whether the request is a cross-origin request or whether the cross-origin request is successful. If you set this parameter to False, the Vary: Origin header is not returned. 
// request.setResponseVary(Boolean.TRUE);
ossClient.setBucketCORS(request);

// Shut down the OSSClient instance. 
ossClient.shutdown();           
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Model\CorsConfig;
use OSS\Model\CorsRule;

// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
$accessKeyId = "yourAccessKeyId";
$accessKeySecret = "yourAccessKeySecret";
// Set endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Specify the name of the bucket. Example: examplebucket. 
$bucket= "examplebucket";

$corsConfig = new CorsConfig();
$rule = new CorsRule();
// Specify the response headers based on which to allow cross-origin requests. You can specify multiple allowed headers. Only one asterisk (*) can be used as the wildcard character for each allowed header. 
// If you do not have special requirements, we recommend that you set AllowedHeader to an asterisk (*). 
$rule->addAllowedHeader("*");
// Specify the response headers for allowed access requests from applications. You can specify multiple exposed headers. Exposed headers cannot contain asterisks (*). 
$rule->addExposeHeader("x-oss-header");
// Specify the origins from which cross-origin requests are allowed. You can specify multiple allowed origins. Only one asterisk (*) can be used as the wildcard character for each allowed origin. 
$rule->addAllowedOrigin("https://example.com:8080");
$rule->addAllowedOrigin("https://*.aliyun.com");
// If you set AllowedOrigin to an asterisk (*), requests from all origins are allowed. 
//$rule->addAllowedOrigin("*");
// Specify the HTTP methods that cross-origin requests are allowed to use. 
$rule->addAllowedMethod("POST");
// Specify the period of time in which the browser can cache the response to an OPTIONS preflight request for specific resources. Unit: seconds. 
$rule->setMaxAgeSeconds(10);
// You can configure up to 10 CORS rules for each bucket. 
$corsConfig->addRule($rule);

try{
    $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

    // The existing rules are overwritten. 
    $ossClient->putBucketCors($bucket, $corsConfig);
} catch(OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . ": OK" . "\n");            
const OSS = require('ali-oss');

const client = new OSS({
  // Set yourRegion to the endpoint of the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set yourRegion to oss-cn-hangzhou. 
  region: 'yourRegion',
  // Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine operations and maintenance. To create a RAM user, log on to the RAM console. 
  accessKeyId: 'yourAccessKeyId',
  accessKeySecret: 'yourAccessKeySecret',
  // Specify the name of the bucket for which you want to configure CORS rules. 
  bucket: 'yourBucket'
});

const rules = [{
        // Specify the origin of allowed cross-origin requests. You can set the origin to an asterisk (*) wildcard to allow requests from all regions. 
        allowedOrigin: 'http://example.com',
        // Specify the method of allowed cross-origin requests, including GET, PUT, DELETE, POST, and HEAD. 
        allowedMethod: 'GET',
        // Specify the header included in the responses to allowed cross-origin requests. We recommend that you use an asterisk (*) wildcard unless otherwise specified. 
        allowedHeader: '*',
       // Specify the response header that can be obtained by web applications, such as an XMLHttpRequest object in JavaScript. The asterisk (*) wildcard is not supported. 
        exposeHeader: 'Content-Length',
       // Specify the time period during which the browser can cache the response to a preflight OPTIONS request for a specific resource. Unit: seconds. 
        maxAgeSeconds: '30'
      }];
      // You can configure up to 10 CORS rules. If a new rule that is the same as an existing rule is configured, the existing rule is overwritten. 
      const putResult = await client.putBucketCORS(bucket, rules);            
# -*- coding: utf-8 -*-
import oss2
from oss2.models import BucketCors, CorsRule

# The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine Q&M. To create a RAM user, log on to the RAM console. 
auth = oss2.Auth('yourAccessKeyId', 'yourAccessKeySecret')
# Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. 
# Specify the name of the bucket. Example: examplebucket. 
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')

rule = CorsRule(allowed_origins=['*'],
                allowed_methods=['GET', 'HEAD'],
                allowed_headers=['*'],
                max_age_seconds=1000)

# The existing rules are overwritten. 
bucket.put_bucket_cors(BucketCors([rule]))            
using Aliyun.OSS;
using Aliyun.OSS.Common;

// Set endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
var accessKeyId = "yourAccessKeyId";
var accessKeySecret = "yourAccessKeySecret";
// Specify the name of the bucket. Example: examplebucket. 
var bucketName = "examplebucket";

// Create an OSSClient instance. 
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    var request = new SetBucketCorsRequest(bucketName);
    var rule1 = new CORSRule();
    // Specify the origins from which cross-origin requests are allowed. 
    rule1.AddAllowedOrigin("http://example.com");
    // Specify the HTTP methods that cross-origin requests are allowed to use, including PUT, POST, GET, DELETE, and HEAD. 
    rule1.AddAllowedMethod("POST");
    // AllowedHeaders and ExposeHeaders do not support wildcard characters. 
    rule1.AddAllowedHeader("*");
    // Specify the response headers for allowed access requests from applications. 
    rule1.AddExposeHeader("x-oss-test");
    // You can configure up to 10 CORS rules for the bucket. 
    request.AddCORSRule(rule1);
    var rule2 = new CORSRule();
    // You can use only one asterisk (*) as the wildcard character for AllowedOrigins and AllowedMethods in a CORS rule. The asterisk (*) wildcard character specifies that all origins or operations are allowed. 
    rule2.AddAllowedOrigin("http://example.net");
    rule2.AddAllowedMethod("GET");
    // Specify whether the headers that are specified by Access-Control-Request-Headers in the OPTIONS preflight request are allowed. 
    rule2.AddExposeHeader("x-oss-test2");
    // Specify the period of time in which the browser can cache the response to an OPTIONS preflight request for specific resources. Unit: seconds. 
    rule2.MaxAgeSeconds = 100;
    request.AddCORSRule(rule2);
    // Configure the CORS rules. 
    client.SetBucketCors(request);
    Console.WriteLine("Set bucket:{0} Cors succeeded ", bucketName);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error info: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}
package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // Create an OSSClient instance. 
    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify the actual endpoint. 
    // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    
    // Specify the name of the bucket. Example: examplebucket. 
    bucketName := "examplebucket"

    rule1 := oss.CORSRule{
        AllowedOrigin: []string{"*"},
        AllowedMethod: []string{"PUT", "GET"},
        AllowedHeader: []string{},
        ExposeHeader:  []string{},
        MaxAgeSeconds: 200,
    }

    rule2 := oss.CORSRule{
        AllowedOrigin: []string{"http://example.com", "http://example.net"},
        AllowedMethod: []string{"POST"},
        AllowedHeader: []string{"Authorization"},
        ExposeHeader:  []string{"x-oss-test", "x-oss-test1"},
        MaxAgeSeconds: 100,
    }

    // Configure the CORS rules. 
    err = client.SetBucketCORS(bucketName, []oss.CORSRule{rule1, rule2})
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
}
            
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize OSS account information. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";

    /* Initialize resources such as network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);

    SetBucketCorsRequest request(BucketName);

    /* Configure CORS rules. */
    auto rule1 = CORSRule();
    /* Specify the origins from which cross-origin requests are allowed. */
    rule1.addAllowedOrigin("http://example.com");
    /* Specify the HTTP methods that cross-origin requests are allowed to use, including GET, PUT, POST, DELETE, and HEAD. */
    rule1.addAllowedMethod("POST");
    /* Specify whether the headers that are specified by Access-Control-Request-Headers in the OPTIONS preflight request are allowed. */
    rule1.addAllowedHeader("*");
    /* Specify the response headers for allowed access requests from applications. */
    rule1.addExposeHeader("x-oss-test");
    /* You can configure up to 10 CORS rules for the bucket. */
    request.addCORSRule(rule1);

    auto rule2 = CORSRule();
    rule2.addAllowedOrigin("http://example.net");
    rule2.addAllowedMethod("GET");
    rule2.addExposeHeader("x-oss-test2");
    rule2.setMaxAgeSeconds(100);
    request.addCORSRule(rule2);

    auto outcome = client.SetBucketCors(request);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "SetBucketCors fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}

Use ossutil

For more information about how to use ossutil to configure CORS rules, see Add or modify CORS configurations for a bucket.

Use the RESTful API

If your business requires a high level of customization, you can directly call RESTful APIs. To directly call an API, you must include the signature calculation in your code. For more information, see PutBucketCors.

FAQ