全部產品
Search
文件中心

:OSS設定跨域資源共用CORS

更新時間:Jun 26, 2024

預設情況下,由於同源策略(Same-Origin Policy)的限制,網頁瀏覽器在執行JavaScript時會限制跨域請求,只允許請求同一域或源的資源。跨域資源共用CORS(Cross-Origin Resource Sharing)簡稱跨域訪問,允許網頁瀏覽器向不同域或源的伺服器發起跨域請求。通過跨網域設定可以實現在您的網站上使用JavaScript請求非同源的OSS對象連結而不會出現跨域問題。

同源檢測

跨域訪問是瀏覽器出於安全考慮而設定的一個限制,即同源策略,是用於隔離潛在惡意檔案的關鍵安全機制。當A、B兩個網站屬於不同域時,來自於A網站頁面中的JavaScript代碼訪問B網站時,瀏覽器會拒絕該訪問。

同協議、同網域名稱(或IP)以及同連接埠視為同域。兩個頁面的協議、網域名稱和連接埠(如果指定了連接埠)相同,則視為同源。下表給出了相對http://www.aliyun.com/org/test.html的同源檢測樣本:

URL

訪問是否成功

原因

http://www.aliyun.com/org/other.html

協議、網域名稱、連接埠相同

http://www.aliyun.com/org/internal/page.html

協議、網域名稱、連接埠相同

https://www.aliyun.com/page.html

協議不同(HTTPS)

http://www.aliyun.com:22/dir/page.html

連接埠不同(22)

http://www.alibabacloud.com/help/other.html

網域名稱不同

從上表中可以看出,協議、網域名稱或者連接埠不同的情況下,瀏覽器會拒絕該來源的訪問。如果要允許這些來源的訪問,需要設定跨域規則。

注意事項

  • 每個Bucket最多可以配置20條跨域規則。

  • 當OSS收到一個跨域請求(或者OPTIONS請求)時,會讀取Bucket對應的CORS規則,然後進行相應的許可權檢查。OSS會依次檢查每一條規則,使用第一條匹配的規則來允許請求並返回對應的Header。如果所有規則都匹配失敗,則不附加任何CORS相關的Header。

  • 如果您開啟了CDN加速,並且需要進行跨域訪問時,您需要在CDN控制台配置跨域規則。具體步驟,請參見CDN如何配置跨域資源共用(CORS)

CORS規則

OSS支援根據需求靈活配置CORS規則,實現允許或者拒絕相應的跨域請求。CORS規則僅用來決定是否附加CORS相關的Header,是否攔截跨域請求由瀏覽器決定。

以下兩種情況需選中返回Vary: Origin以避免本機快取錯亂。

重要

選中返回Vary: Origin後,可能會造成瀏覽器訪問次數或者CDN回源次數增加。

  • 同時存在CORS和非CORS請求

    例如實際請求中在<img>標籤下發起非CORS請求,在fetch下發起CORS請求。

    <!doctype html>
    <html>
    <head>
     <meta charset="UTF-8">
     <title>CORS Test</title>
    </head>
    <body>
    <!--非CORS請求-->
    <img src="https://examplebucket.oss-cn-beijing.aliyuncs.com/exampleobject.txt" alt="">
    <script>
      <!--CORS請求-->
     fetch("https://examplebucket.oss-cn-beijing.aliyuncs.com/exampleobject.txt").then(console.log)
    </script>
    </body>
    </html>
  • Origin頭存在多種可能值

    例如實際應用中指定允許的跨域請求來源Origin頭為http://www.example.com以及https://www.example.org

操作步驟

使用OSS控制台

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇數據安全 > 跨域設置

  4. 跨域設置頁面,單擊創建規則

  5. 跨域規則面板,按以下說明設定跨域規則。

    參數

    是否必須

    說明

    來源

    指定允許的跨域請求的來源。配置規則如下:

    • 允許多條匹配規則,多條規則需換行填寫。

    • 網域名稱需包含協議名,例如HTTP、HTTPS。

    • 支援萬用字元星號(*),每條匹配規則最多允許使用一個星號(*)。

    • 如果網域名稱使用的不是預設連接埠,還需要攜帶連接埠號碼。例如https://www.example.com:8080

    網域名稱配置樣本如下:

    • 匹配指定網域名稱時,填寫完整網域名稱,例如https://www.example.com。

    • 匹配泛次層網域,可使用萬用字元星號(*)。例如https://*.example.com。

    • 匹配所有網域名稱,可直接填寫萬用字元星號(*)。

    允許 Methods

    指定允許的跨域要求方法。

    允許 Headers

    指定允許跨域請求的回應標頭。配置規則如下:

    • 格式為key:value,例如content-type:text/plain,大小寫不敏感。

    • 允許多條匹配規則,多條規則需換行填寫。

    • 支援萬用字元星號(*),每條匹配規則最多允許使用一個星號(*)。建議沒有特殊需求的情況下設定為星號(*)。

    暴露 Headers

    指定允許使用者從應用程式中訪問的回應標頭,例如一個JavaScript的XMLHttpRequest對象。不允許使用星號(*)萬用字元。

    建議暴露的常見Headers如下:

    • x-oss-request-id

      在您使用OSS服務遇到問題時,請憑藉此Request ID請求支援人員協助排查並解決您遇到的問題。

    • ETag

      可用於檢查Object內容是否發生變化。

    緩存時間(秒)

    指定瀏覽器對特定資源的預取(OPTIONS)請求返回結果的緩衝時間,單位為秒。

    返回 Vary: Origin

    配置是否返回Vary: Origin Header

    如果實際應用中同時存在CORS和非CORS請求,或者Origin頭有多種可能值時,建議選中返回 Vary: Origin以避免本機快取錯亂。

    重要

    選中返回 Vary: Origin後,可能會造成瀏覽器訪問次數或者CDN回源次數增加。

  6. 單擊確定

使用阿里雲SDK

以下僅列舉常見SDK的跨網域設定的程式碼範例。關於其他SDK的跨網域設定的程式碼範例,請參見SDK簡介

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.SetBucketCORSRequest;
import java.util.ArrayList;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";

        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            SetBucketCORSRequest request = new SetBucketCORSRequest(bucketName);

            // 每個儲存空間最多允許設定10條跨域規則。
            ArrayList<SetBucketCORSRequest.CORSRule> putCorsRules = new ArrayList<SetBucketCORSRequest.CORSRule>();

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

            ArrayList<String> allowedOrigin = new ArrayList<String>();
            // 指定允許跨域請求的來源。
            allowedOrigin.add( "http://example.com");

            ArrayList<String> allowedMethod = new ArrayList<String>();
            // 指定允許的跨域要求方法(GET/PUT/DELETE/POST/HEAD)。
            allowedMethod.add("GET");

            ArrayList<String> allowedHeader = new ArrayList<String>();
            // 是否允許預取指令(OPTIONS)中Access-Control-Request-Headers頭中指定的Header。
            allowedHeader.add("x-oss-test");

            ArrayList<String> exposedHeader = new ArrayList<String>();
            // 指定允許使用者從應用程式中訪問的回應標頭。
            exposedHeader.add("x-oss-test1");
            // AllowedOrigins和AllowedMethods最多支援一個星號(*)萬用字元。星號(*)表示允許所有的域來源或者操作。
            corRule.setAllowedMethods(allowedMethod);
            corRule.setAllowedOrigins(allowedOrigin);
            // AllowedHeaders和ExposeHeaders不支援萬用字元。
            corRule.setAllowedHeaders(allowedHeader);
            corRule.setExposeHeaders(exposedHeader);
            // 指定瀏覽器對特定資源的預取(OPTIONS)請求返回結果的緩衝時間,單位為秒。
            corRule.setMaxAgeSeconds(10);

            // 最多允許10條規則。
            putCorsRules.add(corRule);
            // 已存在的規則將被覆蓋。
            request.setCorsRules(putCorsRules);
            // 指定是否返回Vary: Origin頭。指定為TRUE,表示不管發送的是否為跨域請求或跨域請求是否成功,均會返回Vary: Origin頭。指定為False,表示任何情況下都不會返回Vary: Origin頭。
            // request.setResponseVary(Boolean.TRUE);
            ossClient.setBucketCORS(request);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                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\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
use OSS\Model\CorsConfig;
use OSS\Model\CorsRule;

// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 填寫Bucket名稱,例如examplebucket。
$bucket= "examplebucket";

$corsConfig = new CorsConfig();
$rule = new CorsRule();
// 設定允許跨域請求的回應標頭。AllowedHeader可以設定多個,每個AllowedHeader中最多隻能使用一個萬用字元星號(*)。
// 建議無特殊需求時設定AllowedHeader為星號(*)。
$rule->addAllowedHeader("*");
// 設定允許使用者從應用程式中訪問的回應標頭。ExposeHeader可以設定多個,ExposeHeader中不支援使用萬用字元星號(*)。
$rule->addExposeHeader("x-oss-header");
// 設定允許的跨域請求的來源。AllowedOrigin可以設定多個,每個AllowedOrigin中最多隻能使用一個萬用字元星號(*)。
$rule->addAllowedOrigin("https://example.com:8080");
$rule->addAllowedOrigin("https://*.aliyun.com");
// 設定AllowedOrigin為星號(*)時,表示允許所有域的來源。
//$rule->addAllowedOrigin("*");
// 設定允許的跨域要求方法。
$rule->addAllowedMethod("POST");
// 設定瀏覽器對特定資源的預取(OPTIONS)請求返回結果的緩衝時間,單位為秒。
$rule->setMaxAgeSeconds(10);
// 每個Bucket最多支援添加10條規則。
$corsConfig->addRule($rule);
// 設定是否返回Vary: Origin頭,取值為false表示任意情況下均不返回Vary: Origin頭
$corsConfig->setResponseVary(false);

try{
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);

    // 已存在的規則將被覆蓋。
    $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({
  // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
  region: 'yourRegion',
  // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  // 填寫Bucket名稱。
  bucket: 'yourBucket'
});

const rules = [{
        // 指定允許跨域請求的來源,支援萬用字元星號(*),表示允許所有的來源域。
        allowedOrigin: 'http://example.com',
        // 指定允許的跨域要求方法,支援GET、PUT、DELETE、POST和HEAD方法。
        allowedMethod: 'GET',
        // 指定允許跨域請求的回應標頭。建議無特殊情況下將此項設定為萬用字元星號(*)。
        allowedHeader: '*',
        // 指定允許使用者從應用程式中訪問的回應標頭,例如一個JavaScript的XMLHttpRequest對象。不允許使用萬用字元星號(*)。
        exposeHeader: 'Content-Length',
        // 指定瀏覽器對特定資源的預取(OPTIONS)請求返回結果的緩衝時間,單位為秒。
        maxAgeSeconds: '30'
  },
];
// 最多允許設定10條跨域資源共用規則。如果配置了相同的規則,則已存在的規則將被覆蓋。
client.putBucketCORS("yourBucket", rules).then((r) => {
  console.log(r);
});           
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import BucketCors, CorsRule

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱,例如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)

# 已存在的規則將被覆蓋。
bucket.put_bucket_cors(BucketCors([rule]))            
using Aliyun.OSS;
using Aliyun.OSS.Common;

// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填寫Bucket名稱,例如examplebucket。
var bucketName = "examplebucket";

// 建立OSSClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    var request = new SetBucketCorsRequest(bucketName);
    var rule1 = new CORSRule();
    // 指定允許跨域請求的來源。
    rule1.AddAllowedOrigin("http://example.com");
    // 指定允許的跨域要求方法(GET/PUT/DELETE/POST/HEAD)。
    rule1.AddAllowedMethod("POST");
    // AllowedHeaders和ExposeHeaders不支援萬用字元。
    rule1.AddAllowedHeader("*");
    // 指定允許使用者從應用程式中訪問的回應標頭。
    rule1.AddExposeHeader("x-oss-test");
    // 最多允許10條規則。
    request.AddCORSRule(rule1);
    var rule2 = new CORSRule();
    // AllowedOrigins和AllowedMethods最多支援一個星號(*)萬用字元。星號(*)表示允許所有的域來源或者操作。
    rule2.AddAllowedOrigin("http://example.net");
    rule2.AddAllowedMethod("GET");
    // 是否允許預取指令(OPTIONS)中Access-Control-Request-Headers頭中指定的Header。
    rule2.AddExposeHeader("x-oss-test2");
    // 指定瀏覽器對特定資源的預取(OPTIONS)請求返回結果的緩衝時間,單位為秒。
    rule2.MaxAgeSeconds = 100;
    request.AddCORSRule(rule2);
    // 設定跨域資源共用規則。
    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"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"os"
)

func main() {
	// yourBucketName填寫Bucket名稱。
	bucketName := "yourBucketName"

	// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 建立OSSClient執行個體。
	// yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
	client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

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

	rule2 := oss.CORSRule{
		AllowedOrigin: []string{"http://www.a.com", "http://www.b.com"},
		AllowedMethod: []string{"GET"},
		AllowedHeader: []string{"Authorization"},
		ExposeHeader:  []string{"x-oss-test-01", "x-oss-test-02"},
		MaxAgeSeconds: 100,
	}

	put := oss.PutBucketCORS{}
	put.CORSRules = []oss.CORSRule{rule1,rule2}
	put.ResponseVary = &isTrue
	// 設定跨域資源共用規則。
	err = client.SetBucketCORSV2(bucketName, put)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	fmt.Println("Set Success")
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS帳號資訊。*/
            
    /* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* 填寫Bucket名稱,例如examplebucket。*/
    std::string BucketName = "examplebucket";

    /* 初始化網路等資源。*/
    InitializeSdk();

    ClientConfiguration conf;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);

    SetBucketCorsRequest request(BucketName);

    /* 設定跨域資源共用規則。*/
    auto rule1 = CORSRule();
    /* 指定允許跨域請求的來源。*/
    rule1.addAllowedOrigin("http://example.com");
    /* 指定允許跨域要求方法(GET/PUT/POST/DELETE/HEAD)。*/
    rule1.addAllowedMethod("POST");
    /* 是否允許預取指令(OPTIONS)中Access-Control-Request-Headers頭中指定的Header。*/
    rule1.addAllowedHeader("*");
    /* 指定允許使用者從應用程式中訪問的回應標頭。*/
    rule1.addExposeHeader("x-oss-test");
    /* 最多指定10條規則。*/
    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()) {
        /* 異常處理。*/
        std::cout << "SetBucketCors fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* 釋放網路等資源。*/
    ShutdownSdk();
    return 0;
}
#include "oss_api.h"
#include "aos_http_io.h"
/* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
const char *endpoint = "yourEndpoint";
/* 填寫Bucket名稱,例如examplebucket。*/
const char *bucket_name = "examplebucket";
void init_options(oss_request_options_t *options)
{
    options->config = oss_config_create(options->pool);
    /* 用char*類型的字串初始化aos_string_t類型。*/
    aos_str_set(&options->config->endpoint, endpoint);
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
    aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
    /* 是否使用了CNAME。0表示不使用。*/
    options->config->is_cname = 0;
    /* 用於設定網路相關參數,比如逾時時間等。*/
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* 在程式入口調用aos_http_io_initialize方法來初始化網路、記憶體等全域資源。*/
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* 用於記憶體管理的記憶體池(pool),等價於apr_pool_t。其實現代碼在apr庫中。*/
    aos_pool_t *pool;
    /* 重新建立一個記憶體池,第二個參數是NULL,表示沒有繼承其它記憶體池。*/
    aos_pool_create(&pool, NULL);
    /* 建立並初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全域配置資訊。*/
    oss_request_options_t *oss_client_options;
    /* 在記憶體池中分配記憶體給options。*/
    oss_client_options = oss_request_options_create(pool);
    /* 初始化Client的選項oss_client_options。*/
    init_options(oss_client_options);
    /* 初始化參數。*/
    aos_string_t bucket;
    aos_table_t *resp_headers = NULL; 
    aos_status_t *resp_status = NULL;
    aos_list_t cors_rule_list;
    oss_cors_rule_t *cors_rule1 = NULL, *cors_rule2 = NULL;
    aos_str_set(&bucket, bucket_name);
    aos_list_init(&cors_rule_list);
    cors_rule1 = oss_create_cors_rule(pool);
    aos_list_add_tail(&cors_rule1->node, &cors_rule_list);
    oss_create_sub_cors_rule(pool, &cors_rule1->allowed_origin_list, "allowed_origin_1_1");
    oss_create_sub_cors_rule(pool, &cors_rule1->allowed_origin_list, "allowed_origin_1_1");
    oss_create_sub_cors_rule(pool, &cors_rule1->allowed_method_list, "PUT");
    oss_create_sub_cors_rule(pool, &cors_rule1->allowed_method_list, "GET");
    oss_create_sub_cors_rule(pool, &cors_rule1->allowed_head_list, "Authorization");
    oss_create_sub_cors_rule(pool, &cors_rule1->expose_head_list, "expose_head_1_1");
    oss_create_sub_cors_rule(pool, &cors_rule1->expose_head_list, "expose_head_1_1");
    cors_rule2 = oss_create_cors_rule(pool);
    aos_list_add_tail(&cors_rule2->node, &cors_rule_list);
    oss_create_sub_cors_rule(pool, &cors_rule2->allowed_origin_list, "allowed_origin_2_1");
    oss_create_sub_cors_rule(pool, &cors_rule2->allowed_origin_list, "allowed_origin_2_2");
    oss_create_sub_cors_rule(pool, &cors_rule2->allowed_method_list, "PUT");
    oss_create_sub_cors_rule(pool, &cors_rule2->allowed_method_list, "GET");
    oss_create_sub_cors_rule(pool, &cors_rule2->allowed_head_list, "Authorization");
    oss_create_sub_cors_rule(pool, &cors_rule2->expose_head_list, "expose_head_2_1");
    oss_create_sub_cors_rule(pool, &cors_rule2->expose_head_list, "expose_head_2_2");
    /* 設定跨域資源共用規則。*/
    resp_status = oss_put_bucket_cors(oss_client_options, &bucket, &cors_rule_list, &resp_headers);
    if (aos_status_is_ok(resp_status)) {
        printf("put bucket cors succeeded\n");
    } else {
        printf("put bucket cors failed\n");      
    }
    /* 釋放記憶體池,相當於釋放了請求過程中各資源分派的記憶體。*/
    aos_pool_destroy(pool);
    /* 釋放之前分配的全域資源。*/
    aos_http_io_deinitialize();
    return 0;
}
require 'aliyun/oss'

client = Aliyun::OSS::Client.new(
  # Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
  endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
  # 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  access_key_id: ENV['OSS_ACCESS_KEY_ID'],
  access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)

# 填寫Bucket名稱,例如examplebucket。
bucket = client.get_bucket('examplebucket')
# 設定跨域資源共用規則。
bucket.cors = [
    Aliyun::OSS::CORSRule.new(
      # 指定允許跨域請求的來源,例如http://example.com。
      :allowed_origins => ['http://example.com', 'http://example.net'],
      # 指定允許的跨域請求的HTTP方法(GET/PUT/DELETE/POST/HEAD)。
      :allowed_methods => ['PUT', 'POST', 'GET'],
      # 在OPTIONS預取指令中允許的header,例如x-oss-test。
      :allowed_headers => ['x-oss-test'],
      # 指定允許使用者從應用程式中訪問的回應標頭。
      :expose_headers => ['x-oss-test1'],
      # 指定瀏覽器對特定資源的預取(OPTIONS)請求返回結果的緩衝時間,單位為秒。
      :max_age_seconds => 100)
]

使用命令列工具ossutil

關於使用ossutil跨網域設定的具體操作, 請參見添加或修改CORS配置

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見PutBucketCors

常見問題

報“No 'Access-Control-Allow-Origin'”錯誤

關於出現該錯誤的原因及解決方案,請參見設定跨域規則後調用OSS時仍然報“No 'Access-Control-Allow-Origin'”的錯誤

使用CDN網域名稱訪問OSS遇到跨域問題

如果您使用CDN網域名稱訪問OSS遇到跨域問題,需在CDN控制台配置跨域規則。具體操作,請參見CDN如何配置跨域資源共用(CORS)

發送跨域請求時報錯Access-Control-Allow-Origin不能為*

報錯Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.時,您可以將OSS中Access-Control-Allow-Origin的值修改為具體的網域名稱,或在前端代碼中設定xhr.withCredentials = false;來解決此問題。詳情請參見發送跨域請求時報錯Access-Control-Allow-Origin不能為*

為什麼配置了兩條跨域規則,沒有都生效?

如果您配置了兩條跨域規則,OSS會依次檢查每一條規則,使用第一條匹配的規則來允許請求並返回對應的Header。