How a Server Explicitly Sets CORS Headers for an HTTP Request

A server explicitly sets CORS headers by including them in the HTTP response to a cross-origin request. These headers instruct the browser whether or not to allow frontend JavaScript from another origin to access the response data.

Example: CORS Headers in an HTTP Response

Access-Control-Allow-Origin: https://example-client.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true

How to Set CORS Headers in Different Environments

1. Node.js / Express

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "https://example-client.com");
  res.header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE");
  res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
  res.header("Access-Control-Allow-Credentials", "true");
  next();
});

Or use the built-in middleware:

const cors = require('cors');

const corsOptions = {
  origin: "https://example-client.com",
  methods: "GET,POST,PUT,DELETE",
  credentials: true
};

app.use(cors(corsOptions));

2. Python / Flask

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources={r"/api/*": {"origins": "https://example-client.com"}}, supports_credentials=True)

3. Apache HTTP Server

<IfModule mod_headers.c>
  Header set Access-Control-Allow-Origin "https://example-client.com"
  Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE"
  Header set Access-Control-Allow-Headers "Content-Type, Authorization"
  Header set Access-Control-Allow-Credentials "true"
</IfModule>

4. Nginx

location /api/ {
  add_header 'Access-Control-Allow-Origin' 'https://example-client.com' always;
  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
  add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
  add_header 'Access-Control-Allow-Credentials' 'true';
}

Preflight Requests (OPTIONS)

For requests that include custom headers or use non-simple HTTP methods (like PUT, DELETE), browsers send a preflight request using OPTIONS.

To support that, servers should handle OPTIONS requests and return appropriate CORS headers.

Example in Node.js:

app.options("*", (req, res) => {
  res.header("Access-Control-Allow-Origin", "https://example-client.com");
  res.header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE");
  res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
  res.sendStatus(204);
});

Security Note

Avoid using:

Access-Control-Allow-Origin: *

if you’re sending cookies or Authorization headers. In such cases, use a specific origin and also set:

Access-Control-Allow-Credentials: true

Using Cloudflare to Maintain a Dynamic Origin Whitelist

If your API is hosted behind Cloudflare, you can use Cloudflare Workers or Cloudflare Gateway Rules to dynamically control and enforce CORS logic at the edge — before the request even reaches your origin server.

Example Using a Cloudflare Worker

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request));
});

const allowedOrigins = [
  "https://example-client.com",
  "https://admin.example.com"
];

async function handleRequest(request) {
  const origin = request.headers.get("Origin");
  const response = await fetch(request);
  const newHeaders = new Headers(response.headers);

  if (allowedOrigins.includes(origin)) {
    newHeaders.set("Access-Control-Allow-Origin", origin);
    newHeaders.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    newHeaders.set("Access-Control-Allow-Headers", "Authorization, Content-Type");
    newHeaders.set("Access-Control-Allow-Credentials", "true");
  }

  return new Response(response.body, {
    status: response.status,
    statusText: response.statusText,
    headers: newHeaders
  });
}
  

This gives you full control over origin validation and CORS behavior at the network edge, improving performance and offloading logic from your app servers.

You can even maintain the whitelist in a KV store or external API and update it dynamically without redeploying infrastructure.

Anuj holds professional certifications in Google Cloud, AWS as well as certifications in Docker and App Performance Tools such as New Relic. He specializes in Cloud Security, Data Encryption and Container Technologies.

Initial Consultation

Anuj Varma – who has written posts on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.