OSS設置跨域資源共享CORS
默認情況下,由于同源策略(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://bestwisewords.com/dir/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控制臺
登錄OSS管理控制臺。
單擊Bucket 列表,然后單擊目標Bucket名稱。
在左側導航欄,選擇 。
在跨域設置頁面,單擊創建規則。
在創建跨域規則面板,按以下說明設置跨域規則。
參數
是否必須
說明
來源
是
指定允許的跨域請求的來源。配置規則如下:
允許多條匹配規則,多條規則需換行填寫。
域名需包含協議名,例如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回源次數增加。
單擊確定。
使用阿里云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。
常見問題
CORS配置項常見錯誤
關于CORS配置項常見錯誤及排查方法,請參見OSS跨域資源共享(CORS)錯誤排除。
報“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。