Browsers may block cross-origin requests to Object Storage Service (OSS) due to the same-origin policy, which restricts access to the same protocol, domain, and port. For example, a page at https://www.example.com cannot load resources from https://example-bucket.oss-cn-hangzhou.aliyuncs.com/test.jpg.
Configure CORS rules for your bucket to authorize specific websites to access OSS resources directly.
How it works
CORS requests fall into two types: simple requests (sent directly) and preflight requests (require an authorization check before the main request).
A preflight request is required if any of the following conditions are met:
-
The request uses a method other than
GET,HEAD, orPOST. -
The request uses the
POSTmethod with aContent-Typeother thantext/plain,application/x-www-form-urlencoded, ormultipart/form-data. -
The request includes custom headers, such as
x-oss-*.
When a browser sends a simple request to OSS, the following process occurs:
-
The browser adds an
Originheader to the request. TheOriginheader specifies the origin of the calling page, for example,Origin: https://www.example.com. -
OSS checks the request's HTTP method and
Originheader against the bucket's CORS rules to find a matching rule. If a match is found, OSS includes theAccess-Control-Allow-Originheader in the response. The value of this header is the value of theOriginheader from the initial request. -
The browser receives the response. It allows the request to proceed only if the
Access-Control-Allow-Originheader is present and its value matches the page's domain. Otherwise, the request fails.
A preflight request adds these steps before the simple request flow. If successful, it then proceeds with the same process as a simple request:
-
The browser sends an
OPTIONSrequest that includes the method (Access-Control-Request-Method) and headers (Access-Control-Request-Headers) of the intended main request. -
OSS checks if the method and headers in the request are allowed based on the CORS configuration. If the preflight request includes any method or header not allowed by the rules, the request fails, and the main request is not sent.
Load static website resources
A website at https://www.example.com needs to load images, CSS, and JS files stored in an OSS bucket.
Step 1: Configure a CORS rule
Log on to the OSS console. Navigate to the Content Security > CORS page for the destination bucket and create a rule as follows:
|
Parameter |
Value |
Description |
|
Origin |
|
Restricts access to this website. |
|
Allowed Methods |
|
|
|
Allowed Headers |
Empty |
Not required — simple requests do not trigger preflight. |
|
Exposed Headers |
|
|
|
Cached Timeout (Seconds) |
86400 |
Caches preflight results for 24 hours. |
|
Vary: Origin |
Unchecked |
Not needed for a single, specific origin. |
Step 2: Verify the configuration
Visit https://www.example.com and confirm that OSS resources, such as images, load correctly and that there are no CORS errors in the browser console.
Upload files directly from the frontend
A user on the web page https://app.example.com uploads files, such as avatars and documents, directly to OSS.
Step 1: Configure a CORS rule
Log on to the OSS console. Navigate to the Content Security > CORS page for the destination bucket and create a rule as follows:
|
Parameter |
Value |
Description |
|
Origin |
|
Restricts uploads to this authorized application. |
|
Allowed Methods |
|
|
|
Allowed Headers |
|
Direct uploads use temporary signatures (presigned URLs) rather than a fixed |
|
Exposed Headers |
|
|
|
Cached Timeout (Seconds) |
600 |
A 10-minute cache balances preflight reduction with quick configuration updates. |
|
Vary: Origin |
Checked |
Prevents CDN cache pollution for potential multi-domain deployments. |
Step 2: Verify the configuration
Perform an upload operation on the https://app.example.com page and confirm that the file is successfully uploaded to OSS and that there are no CORS errors in the browser console.
Support for multiple environments
Multiple subdomains for development, testing, and production, such as dev.example.com and app.example.com, need to access the same OSS resources.
Step 1: Configure a CORS rule
Log on to the OSS console. Navigate to the Content Security > CORS page for the destination bucket and create a rule as follows:
|
Parameter |
Value |
Description |
|
Origin |
|
The |
|
Allowed Methods |
|
Supports reading and uploading across all environments. |
|
Allowed Headers |
|
The |
|
Exposed Headers |
|
Supports both download validation and upload result feedback. |
|
Cached Timeout (Seconds) |
3600 |
A 1-hour cache balances performance with debugging flexibility. |
|
Vary: Origin |
Checked |
Required. Instructs CDN to cache responses per |
Step 2: Verify the configuration
Perform access or upload tests on both https://dev.example.com and https://app.example.com to confirm that all operations succeed.
Make API-style calls with authentication
A frontend application at https://api.example.com needs to access protected OSS resources by including custom headers such as Authorization.
Step 1: Configure a CORS rule
Log on to the OSS console. In the destination bucket, navigate to the Content Security > CORS page and create a rule as follows:
|
Parameter |
Value |
Description |
|
Origin |
|
For requests with authentication information, the origin must be a precise, trusted domain. |
|
Allowed Methods |
|
Supports reading, updating, and deleting private resources. |
|
Allowed Headers |
|
Do not use |
|
Exposed Headers |
|
Provides a verification identifier for successful operations and an ID for troubleshooting. |
|
Cached Timeout (Seconds) |
600 |
A shorter cache (10 minutes) ensures security policy changes apply quickly. |
|
Vary: Origin |
Select |
Ensures CDN caches responses separately per origin. |
Step 2: Verify the configuration
Initiate a request with an Authorization header from the https://api.example.com page and confirm that you can access the protected OSS resource.
Apply in production
Security best practices
Follow the principle of least privilege.
-
Configure
Origin (AllowedOrigin)precisely: Avoid setting*forSourcesunless your bucket is fully public. Specify exact domains, such ashttps://www.example.com. -
Restrict
Allowed Methods: Expose only the HTTP methods your application needs. For read-only sites, configure onlyGETandHEAD. -
Specify
Allowed Headersexplicitly: For authenticated requests (withAuthorizationheader), do not use*. List all required request headers explicitly.
Performance best practices
-
Optimize the preflight cache: A reasonable
MaxAgeSecondsvalue, such as86400seconds (24 hours), significantly reduces preflight requests, lowering latency and cost. -
Evaluate the impact of
Vary: Origin: EnablingVary: Originsolves cache poisoning issues but increases CDN caching complexity. This may lower cache hit ratio and increase back-to-origin traffic (additional cost and latency). Enable only after evaluating your traffic patterns.
CDN acceleration
If your bucket is accelerated by Alibaba Cloud CDN and accessed via a CDN domain, cross-origin requests will first reach a CDN Point of Presence (PoP). You must configure CORS rules in the CDN console, not in the OSS console. The CORS configuration in OSS only applies to requests made directly to the OSS origin domain. For details, see Configure cross-origin resource sharing (CORS).
Parameters of CORS rules
You can configure up to 20 CORS rules for each bucket. OSS evaluates rules sequentially from top to bottom and applies the first one that matches the request. Once a match is found, OSS does not check subsequent rules.
|
Parameter |
Required |
Description |
|
Origin (AllowedOrigin) |
Yes |
Specifies the websites (origin domains) that are allowed to make cross-origin requests to OSS resources.
|
|
Allowed Methods (AllowedMethod) |
Yes |
Specifies the allowed HTTP methods.
|
|
Allowed Headers (AllowedHeader) |
No |
Applies to preflight requests and determines which HTTP headers can be included in the actual request.
|
|
Exposed Headers (ExposeHeader) |
No |
Specifies which OSS response headers are accessible to client-side JavaScript.
|
|
Cached Timeout (MaxAgeSeconds) |
No |
Specifies the time in seconds that a browser can cache the result of a preflight
|
|
Vary: Origin |
No |
Determines whether to add the
Important
Enabling this option may decrease the CDN cache hit ratio. |
FAQ
Error: No 'Access-Control-Allow-Origin' header is present on the requested resource.
This error typically means the browser has cached an old response without CORS headers, or no CORS rule matches the incoming request.
Clear your browser cache and retest. If the error persists, verify your CORS rules:
-
In the navigation pane on the left, choose Content Security > CORS.
-
On the CORS page, click Create Rule.
-
In the Create CORS Rule panel, set Origin to
*, select all Allowed Methods, set Allowed Headers to*, set Exposed Headers toETagandx-oss-request-id, set Cache Timeout (Seconds) to 0, select Vary: Origin, and click OK. -
If the issue persists, log on to any server and run the following command to view the cross-origin request headers.
curl -v -o output_file.txt -H 'Origin:[$URL2]' '[$URL1]'Note-
[URL1] is the URL of the requested OSS resource.
-
[URL2] is the origin address you configured in the CORS rule.
The system displays an output similar to the following.

-
If the response includes a matching CORS header, the issue is likely browser or network caching. An earlier non-CORS request may have been cached locally, and a subsequent cross-origin request fetched this cached response instead of getting a fresh one from the server. Try the following solutions:
-
Press Ctrl+F5 in your browser to clear the cache, then test if the issue persists.
-
Set Cached-Seconds to 0 in the CORS rule. This forces every request to re-fetch CORS authorization from the server.
NoteYou can set the
cache-controlof an object tono-cachewhen you upload it. For objects that are already uploaded, you can ossutil to change this setting. For more information, see set-meta (Manage object metadata). -
Use CDN to accelerate OSS, ensuring all CDN-served requests include CORS headers.
-
-
If the response contains two CORS headers or a header that does not match your OSS configuration, the issue is likely caused by using CDN to accelerate OSS:
-
Log on to the CDN console and temporarily disable CDN acceleration for the domain name to confirm that the cross-origin issue is resolved.
-
After confirmation, click the specific domain name, then navigate to Cache Configuration > Node HTTP Response Header.
-
Set custom HTTP response headers as needed.
-
-
-
If the CORS issue is still not resolved, see Common errors and solutions for OSS CORS for further troubleshooting.
Error: The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin.
The server returned an Access-Control-Allow-Origin header, but its value does not match the request's Origin. This is often a caching problem — a browser or CDN caches the response for one domain and serves it to another.
Enable the Vary: Origin option in your CORS rule to prevent cache conflicts between different websites, or clear your browser cache before retrying.
Error: 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'.
This error occurs because the frontend sent a credentialed request (Access-Control-Allow-Credentials is True), but Access-Control-Allow-Origin is set to *. Browsers prohibit this combination to prevent any site from accessing sensitive data like cookies or Authorization tokens.
-
If you need credentials, change
Sourcesfrom*to a specific domain (e.g.,https://example.com). -
If you do not need credentials, set
xhr.withCredentialstofalsein your frontend code and ensureAccess-Control-Allow-Credentialsisfalseon the server.
How to improve slow cross-origin loading from OSS?
Cross-origin loading speed depends on network latency between the client and the OSS bucket. A cross-origin request includes an Origin header. For long-distance access (for example, China (Hong Kong) to Chinese mainland), use a Transfer Acceleration endpoint to optimize the network path.
Transfer Acceleration optimizes network paths to improve global data transfer speeds.