How to Enable CORS on Pages Functions?

Benjamin CarterBenjamin Carter
8 min read
Spt 8, 2025

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 to true, and Access-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.