Skip to content

Apache CORS Configuration — Adding Cross-Origin Headers with mod_headers

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Apache CORS Configuration. We cover key concepts, practical examples, and best practices to help you master this topic.

Apache HTTP Server provides CORS header injection through mod_headers, with preflight handling via mod_rewrite and dynamic origin validation using SetEnvIf directives.

What You'll Learn

  • Enabling mod_headers for CORS in Apache
  • Writing Header directives for Access-Control-* headers
  • Handling OPTIONS preflight with mod_rewrite

Why It Matters

Apache still powers many shared hosting and enterprise environments. CORS configuration at the Apache layer allows centralized policy management without application changes. DodaTech's legacy partner portal uses Apache with mod_headers for CORS.

flowchart LR
    A["Apache HTTPD"] --> B{"Request"}
    B --> C["mod_rewrite checks method"]
    C -->|"OPTIONS"| D["Return 200 with CORS headers"]
    C -->|"Other"| E["mod_headers adds CORS headers"]
    E --> F["Proxy or serve static files"]
    D --> G["Response to browser"]
    F --> G

Code Examples

# Basic Apache CORS configuration in .htaccess or httpd.conf
<IfModule mod_headers.c>
    # Allow specific origin
    Header set Access-Control-Allow-Origin "https://app.example.com"

    # Allow credentials
    Header set Access-Control-Allow-Credentials "true"

    # Expose custom headers
    Header set Access-Control-Expose-Headers "X-RateLimit-Remaining, X-Request-ID"

    # Handle preflight request
    SetEnvIf Request_Method OPTIONS $cors_preflight=1
    Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" env=cors_preflight
    Header set Access-Control-Allow-Headers "Content-Type, Authorization" env=cors_preflight
    Header set Access-Control-Max-Age "86400" env=cors_preflight
    Header set Content-Type "text/plain" env=cors_preflight

    # Return 204 for preflight
    RewriteCond %{REQUEST_METHOD} OPTIONS
    RewriteRule ^(.*)$ $1 [R=204,L]
</IfModule>
# Dynamic CORS with SetEnvIf
SetEnvIf Origin "^(https://app\.example\.com)$" ALLOWED_ORIGIN=$1
SetEnvIf Origin "^(https://admin\.example\.com)$" ALLOWED_ORIGIN=$1
SetEnvIf Origin "^(https://dashboard\.example\.com)$" ALLOWED_ORIGIN=$1

Header set Access-Control-Allow-Origin "%{ALLOWED_ORIGIN}e" env=ALLOWED_ORIGIN
Header set Access-Control-Allow-Credentials "true" env=ALLOWED_ORIGIN

<If "env('ALLOWED_ORIGIN') == '' && req('Origin') != ''">
    Header set Access-Control-Allow-Origin "null"
</If>
# .htaccess example for shared hosting
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} OPTIONS
    RewriteRule ^(.*)$ $1 [R=204,L]
</IfModule>

<IfModule mod_headers.c>
    Header always set Access-Control-Allow-Origin "https://app.example.com"
    Header always set Access-Control-Allow-Credentials "true"
    Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
    Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
    Header always set Access-Control-Expose-Headers "X-Request-ID"
    Header always set Access-Control-Max-Age "3600"
</IfModule>
# Test Apache CORS configuration
curl -I -H "Origin: https://app.example.com" \
  https://api.example.com/api/data | grep -i "access-control"

# Test preflight
curl -X OPTIONS -I \
  -H "Origin: https://app.example.com" \
  https://api.example.com/api/data | grep -i "access-control"

Common Mistakes

1. Using Header Set Without the Always Parameter

Header set applies only to success responses. Use Header always set to apply to all responses.

2. Not Enabling mod_headers and mod_rewrite

These modules must be enabled in Apache configuration for CORS directives to work.

3. Blocked by Apache's AllowOverride

If AllowOverride is not set to All, .htaccess CORS directives may be ignored.

4. Incorrect SetEnvIf Syntax

SetEnvIf patterns use regex syntax. Test patterns carefully to avoid blocking valid origins.

5. Not Handling OPTIONS Method Correctly

Without the RewriteRule for OPTIONS, preflight requests proceed to the application and may fail.

Practice Questions

  1. What Apache module is required for CORS headers?
  2. How do you apply CORS headers to all responses including errors?
  3. What directive handles dynamic origin validation in Apache?
  4. How do you handle OPTIONS preflight in Apache?
  5. What is the difference between Header set and Header append?

Answers:

  1. mod_headers.
  2. Use Header always set instead of Header set.
  3. SetEnvIf with regex patterns to capture and validate the Origin header.
  4. Use RewriteRule to return a 204 response for OPTIONS requests.
  5. Header set replaces any existing header; Header append adds to existing header values.

Challenge: Configure Apache as a reverse proxy for a Node.js API with CORS. Implement dynamic origin validation using SetEnvIf with regex patterns, handle OPTIONS preflight requests, and add logging for CORS rejections using CustomLog with environment variables.

FAQ

Can I use Apache's mod_proxy with CORS?

Yes. ProxyPass and ProxyPassReverse work with CORS headers. The CORS headers are added to the proxied response using the same Header directives.

How do I allow multiple origins in Apache?

Use SetEnvIf with multiple lines for each allowed origin pattern. The matched origin is stored in an environment variable and used in Header set.

What is the performance impact of CORS in Apache?

Apache's CORS processing using SetEnvIf and Header adds minimal overhead. mod_rewrite rules for OPTIONS are fast since they return early without backend processing.

Can I configure CORS for specific directories only?

Yes. Place CORS directives inside , , or blocks, or in .htaccess files within specific directories.

How do I debug CORS in Apache?

Enable RewriteLog (Apache 2.2) or use LogLevel alert rewrite:trace6 (Apache 2.4+). Check Apache error logs for SetEnvIf and Header processing.

Mini Project

Set up Apache as a CORS gateway for a multi-service architecture. Implement dynamic origin whitelisting with SetEnvIf, preflight handling, credential support, and logging. Create a test suite that verifies CORS headers for allowed origins, blocked origins, and OPTIONS requests. Generate a configuration report.

What's Next

Master CORS error handling and debugging techniques, then explore CORS testing with curl and Postman.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro