How to Enable CORS on Pages Functions?

Cross-Origin Resource Sharing (CORS) is a security mechanism implemented by browsers to control how web applications interact with resources from different origins. By default, the same-origin policy restricts web pages from making requests to servers other than their own domain. CORS relaxes these restrictions by allowing servers to specify, via HTTP headers, which origins are permitted to access their resources.
Key CORS Response Headers and Their Functions
- Access-Control-Allow-Origin: Specifies the origins allowed to access the resource. Using * allows all origins (not recommended for sensitive data); specifying a particular origin (e.g., https://app.example) enhances security.
- Access-Control-Allow-Methods: Lists the HTTP methods permitted when accessing the resource (e.g., GET, POST, PUT, PATCH, DELETE, OPTIONS).
- Access-Control-Allow-Headers: Specifies which custom headers can be included in the actual request (e.g., Authorization, Content-Type, X-CSRF-Token).
- Access-Control-Allow-Credentials: Indicates whether credentials (such as cookies or HTTP authentication) are allowed. Must be set to true and can only be used with explicit (non-*) origins.
- Access-Control-Max-Age: Defines how long (in seconds) the results of a preflight request can be cached by the browser (e.g., 86400 for 24 hours).
When a request is considered a "non-simple request" (such as those using custom headers or methods other than GET/POST), the browser automatically sends a preflight OPTIONS request to the server. The server must return the appropriate CORS headers; otherwise, the browser will block the actual request.
Solving Cross-Origin Issues with Pages Functions
Pages Functions provide a serverless code execution environment running on EdgeOne edge nodes. Developers only need to write business logic and configure trigger rules—no server infrastructure management is required. Code executes elastically and securely at edge nodes close to end users.
Solving CORS via Headers API
Typical Code Example:
// functions/api/hello.ts
export async function onRequest({ request }) {
const origin = request.headers.get("Origin");
// Business logic or proxying upstream requests
const response = await fetch(request);
// Set CORS response headers
response.headers.set("Access-Control-Allow-Origin", origin || "*");
response.headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.headers.set("Access-Control-Max-Age", "86400");
return response;
}
Note: If you need to support credentials (such as cookies), you must set Access-Control-Allow-Origin
to a specific domain and add Access-Control-Allow-Credentials:
true
.
Geolocation-Based CORS
You can also use EdgeOne's geolocation data to implement region-specific CORS policies:
// functions/api/hello.ts
export async function onRequest({ request }) {
const origin = request.headers.get("Origin");
const country = (request.eo.geo && request.eo.geo.country) || "US";
const corsMap = {
US: { origins: ["https://us.example.com"], credentials: true },
CA: { origins: ["https://ca.example.com"], credentials: true },
EU: { origins: ["https://eu.example.com"], credentials: true },
};
const region = corsMap[country] || { origins: ["https://global.example.com"], credentials: false };
const isAllowed = origin && region.origins.includes(origin);
const headers = {
"Access-Control-Allow-Origin": isAllowed ? origin : "null",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Credentials": region.credentials.toString(),
"Access-Control-Max-Age": "86400",
};
if (request.method === "OPTIONS") {
return new Response(null, { status: 204, headers });
}
return new Response(JSON.stringify({ country }), {
headers: { ...headers, "content-type": "application/json; charset=UTF-8" },
});
}
Test your setup
# Pre‑flight
curl -i -X OPTIONS https://your-domain.edgeone.app/api/hello \
-H "Origin: https://app.example" \
-H "Access-Control-Request-Method: POST"
# Simple request
curl -i https://your-domain.edgeone.app/api/hello \
-H "Origin: https://app.example"
Look for a 200
status on the OPTIONS call and the correct CORS headers in both responses.
Common CORS Scenarios and Solutions
- CORS errors when calling APIs from local frontend development: The API server must include CORS headers that allow the local development domain.
- Third-party applications integrating your API: Dynamically determine the
Origin
and return the corresponding CORS headers as needed to enhance security. - Supporting credentialed cross-origin requests:
Access-Control-Allow-Credentials
must be set totrue
, andAccess-Control-Allow-Origin
cannot be*
.
Summary
CORS is an unavoidable issue in front-end/back-end separation and microservices architectures. By flexibly setting CORS response headers in EdgeOne Pages Functions, you can efficiently and securely address cross-origin access requirements. For more complex scenarios, you can leverage environment variables, KV storage, and other capabilities to implement dynamic authorization and personalized cross-origin strategies.
For advanced usage, please refer to the Pages Functions Documentation.