CORS Tester

20 min read · 4943 words

Test Cross-Origin Resource Sharing headers, simulate preflight requests, and debug CORS errors for any API endpoint. Free, fast, and built for developers who don't want to waste another hour on cryptic browser errors.

Version 2.4.1 100% Free No Signup Required CORS RFC 6454

Last verified: — All CORS header parsing rules confirmed against the latest Fetch Living Standard.

Test Results

Response Headers

HeaderValue

Response Body Preview

Common CORS Errors & Fixes

No 'Access-Control-Allow-Origin' header is present on the requested resource

The server didn't include an Access-Control-Allow-Origin header. Add this header to your server's response with the requesting origin or * for public endpoints. This is by far the most common CORS error developers encounter.

CORS preflight request did not succeed / Response to preflight request doesn't pass

The browser sent an automatic OPTIONS request, and it was rejected. Your server must handle OPTIONS requests explicitly and return the appropriate Access-Control-Allow-Methods and Access-Control-Allow-Headers headers. Many frameworks require separate OPTIONS route handlers.

Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '*'

When sending credentials (cookies or HTTP auth), the server cannot use a wildcard origin. You must set Access-Control-Allow-Origin to the specific requesting origin (e.g., https://myapp.com) and include Access-Control-Allow-Credentials: true.

Method PUT is not allowed by Access-Control-Allow-Methods in preflight response

The preflight response didn't list the requested HTTP method. Add all needed methods to the Access-Control-Allow-Methods header, for example: GET, POST, PUT, DELETE, PATCH, OPTIONS.

Request header field X-Custom-Header is not allowed by Access-Control-Allow-Headers

Custom headers require explicit permission via the preflight response. Add each custom header name to the Access-Control-Allow-Headers header. Common ones include Authorization, Content-Type, and X-Requested-With.

The Complete Guide to CORS Testing in 2026

Cross-Origin Resource Sharing (CORS) is an HTTP-header-based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS relies on a mechanism by which browsers make a "preflight" request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. — Wikipedia

If you've ever spent hours staring at a red CORS error in your browser console, you're not alone. Cross-Origin Resource Sharing is one of the most misunderstood concepts in web development, and it's the reason thousands of developers hit roadblocks when building applications that communicate across different origins. Our CORS tester was built specifically to take the guesswork out of debugging these issues and help you ship your applications faster with confidence.

Whether you're building a single-page application that talks to a REST API, integrating with a third-party service, or just trying to figure out why your fetch request keeps failing even though Postman says everything is fine, this guide and tool will help you understand exactly what's happening behind the scenes and how to fix it.

What Is CORS and Why Does It Exist?

CORS exists because of the Same-Origin Policy (SOP), a fundamental security mechanism built into every modern web browser. The Same-Origin Policy prevents scripts on one origin from reading data from another origin. An "origin" is defined as the combination of protocol (http/https), domain, and port number. So https://app.example.com and https://api.example.com are different origins, even though they share the same root domain.

The Same-Origin Policy is essential for security. Without it, a malicious website could make requests to your bank's API using your cookies, read the response containing your account balance and transaction history, and exfiltrate that data to an attacker's server. The SOP prevents this by blocking scripts from reading cross-origin responses.

However, the modern web often requires legitimate cross-origin communication. Your React frontend on app.example.com needs to call your API on api.example.com. Your marketing site needs to load fonts from Google Fonts. Your payment form needs to communicate with Stripe's servers. Your analytics dashboard needs to pull data from multiple microservice endpoints. CORS provides a controlled, standardized way to relax the Same-Origin Policy for these legitimate use cases while maintaining security.

The CORS specification, first proposed as part of the W3C's work on XMLHttpRequest Level 2 and now maintained as part of the Fetch Living Standard, defines a set of HTTP headers that servers use to communicate their cross-origin policies to the browser. When a browser encounters a cross-origin request, it checks for these headers in the server's response. If they're present and permit the specific request being made, the browser allows JavaScript to read the response. If they're missing or don't match what's needed, the browser blocks access to the response — and you see that dreaded red error in your developer console.

How Our CORS Tester Works

Based on our testing and original research into the most common CORS failure patterns across thousands of API endpoints, we designed this tool to test real-world CORS configurations from the browser's perspective. Unlike server-side tools like curl or Postman that bypass CORS entirely (because they aren't browsers), our tester uses the browser's native fetch() API. This means you see exactly what your end users will see when your frontend application makes the same request.

When you enter a target URL and click "Send CORS Request," the tool performs the following steps in sequence:

  1. Constructs the request using your specified HTTP method, custom headers, and request body
  2. Sends the request via fetch() in CORS mode, which is the default mode browsers use for cross-origin requests
  3. Captures the response including the HTTP status code, all accessible response headers, and the response body
  4. Analyzes all CORS-specific headers against the requirements of the specific request that was made
  5. Renders a detailed verdict (PASS, FAIL, or WARN) with specific explanations of what's working and what isn't

It's important to understand a key limitation of browser-based testing: when a CORS request fails, the browser intentionally hides the response details from JavaScript for security reasons. You won't see the actual response headers or body — just a generic network error. This is by design. That's why we also include the "Test Against Our Server" simulation mode that shows you what headers should be present for various configurations and explains the theory without needing an actual cross-origin server. Our testing methodology covers all six CORS response headers and their interactions with each other.

Understanding CORS Headers in Detail

There are six primary CORS response headers. Each one controls a different aspect of cross-origin access, and understanding how they work together is crucial for proper configuration. Let's walk through every single one in depth.

1. Access-Control-Allow-Origin

This is the most important CORS header and the one that causes the majority of CORS errors. It tells the browser which origins are allowed to read the response. It can be set to one of three values:

  • A specific origin like https://myapp.com — only that exact origin can read the response
  • The wildcard * — any origin can read the response (but can't be used with credentials)
  • The null origin — generally not recommended; used in specific edge cases like file:// URIs
// Specific origin (recommended for authenticated APIs)
Access-Control-Allow-Origin: https://myapp.com

// Wildcard (suitable for public APIs)
Access-Control-Allow-Origin: *

A common pattern is to dynamically set this header based on the incoming Origin request header. The server checks if the requesting origin is in its whitelist and, if so, echoes that specific origin back. This allows multiple origins while avoiding the wildcard.

2. Access-Control-Allow-Methods

This header specifies which HTTP methods the server accepts for cross-origin requests. It's primarily used in the response to preflight (OPTIONS) requests. Note that GET, POST, and HEAD are considered "simple" methods and technically don't need to be listed here for simple requests, but it's good practice to include them anyway.

Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS

Be as specific as possible. If your API only uses GET and POST, only list those two methods. Don't include DELETE if no endpoint supports it. This follows the principle of least privilege and reduces your attack surface.

3. Access-Control-Allow-Headers

Lists which request headers the server will accept in cross-origin requests. There's a set of "CORS-safelisted" request headers that don't need explicit listing: Accept, Accept-Language, Content-Language, and Content-Type (but only with values of application/x-www-form-urlencoded, multipart/form-data, or text/plain). Any other headers — like Authorization, X-API-Key, or Content-Type: application/json — must be explicitly listed.

Access-Control-Allow-Headers: Content-Type, Authorization, X-Request-ID, X-API-Key

4. Access-Control-Allow-Credentials

When set to true, this header allows cross-origin requests to include credentials such as cookies, HTTP authentication headers, or client-side TLS certificates. This header has a critical constraint: when it's set to true, the Access-Control-Allow-Origin header must specify an exact origin — the wildcard * is not allowed. The browser will reject the response if both are present.

Access-Control-Allow-Credentials: true
// Requires: Access-Control-Allow-Origin: https://specific-origin.com (NOT *)

On the client side, you also need to set credentials: 'include' in your fetch options (or withCredentials: true for XMLHttpRequest) for the browser to actually send cookies with the request.

5. Access-Control-Max-Age

Specifies how long (in seconds) the browser can cache the preflight response. When the browser receives a preflight response with this header, it won't send another preflight for the same request parameters until the cache expires. A value of 86400 (24 hours) is common, but be aware that different browsers enforce different maximums: Chrome 134 caps it at 7200 seconds (2 hours), while Firefox allows up to 86400 seconds (24 hours).

Access-Control-Max-Age: 7200  // 2 hours - works across all browsers

6. Access-Control-Expose-Headers

By default, JavaScript can only read a limited set of "CORS-safelisted" response headers: Cache-Control, Content-Language, Content-Length, Content-Type, Expires, Last-Modified, and Pragma. If your API returns custom response headers that the frontend needs (like pagination info, rate limit data, or request IDs), you must explicitly list them with this header.

Access-Control-Expose-Headers: X-Total-Count, X-Rate-Limit-Remaining, X-Request-ID, Link

The Preflight Request: Deep Dive

The preflight mechanism is one of the most confusing aspects of CORS, and it's the source of a huge percentage of CORS debugging sessions. The browser automatically sends an OPTIONS request before the actual request when any of these "non-simple" conditions are met:

  • The HTTP method is anything other than GET, POST, or HEAD (e.g., PUT, DELETE, PATCH)
  • The request includes custom headers beyond the CORS-safelisted set
  • The Content-Type header is set to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain
  • The request uses ReadableStream in the body
  • Event listeners are registered on the XMLHttpRequestUpload object

The preflight is essentially the browser asking the server: "I'm about to send a PUT request with a custom Authorization header from https://myapp.com — will you accept this?" The preflight request includes two special headers:

OPTIONS /api/resource HTTP/1.1
Host: api.example.com
Origin: https://myapp.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Authorization, Content-Type

The server must respond with the appropriate Access-Control-Allow-* headers. Only if the preflight succeeds does the browser send the actual PUT request. If the preflight fails, the browser stops immediately and reports a CORS error.

A critical mistake many developers make: they configure CORS headers on their API routes but forget to handle the OPTIONS method. Many frameworks require explicit OPTIONS route handlers. If your server returns a 405 Method Not Allowed for OPTIONS requests, every non-simple cross-origin request will fail.

CORS Configuration by Framework

Here's how to configure CORS properly in the most popular backend frameworks. Each example includes credentials support and proper preflight handling.

Express.js / Node.js

const cors = require('cors');  // npm install cors

// Simple: allow specific origin
app.use(cors({
  origin: 'https://myapp.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
  exposedHeaders: ['X-Total-Count', 'X-Rate-Limit-Remaining'],
  credentials: true,
  maxAge: 7200  // 2 hours
}));

// Advanced: dynamic origin validation
app.use(cors({
  origin: function(origin, callback) {
    const whitelist = ['https://myapp.com', 'https://staging.myapp.com'];
    if (!origin || whitelist.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true
}));

Django / Python

# pip install django-cors-headers
# settings.py
INSTALLED_APPS = [
    ...
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # Must be high in the list
    'django.middleware.common.CommonMiddleware',
    ...
]

CORS_ALLOWED_ORIGINS = [
    "https://myapp.com",
    "https://staging.myapp.com",
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS']
CORS_ALLOW_HEADERS = ['content-type', 'authorization', 'x-request-id']
CORS_EXPOSE_HEADERS = ['x-total-count', 'x-rate-limit-remaining']
CORS_PREFLIGHT_MAX_AGE = 7200

Spring Boot / Java

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("https://myapp.com")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
            .allowedHeaders("Content-Type", "Authorization", "X-Request-ID")
            .exposedHeaders("X-Total-Count", "X-Rate-Limit-Remaining")
            .allowCredentials(true)
            .maxAge(7200);
    }
}

Nginx (Reverse Proxy)

location /api/ {
    # Handle preflight
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Request-ID' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Max-Age' 7200 always;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }

    # Actual request headers
    add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header 'Access-Control-Expose-Headers' 'X-Total-Count, X-Rate-Limit-Remaining' always;

    proxy_pass http://backend;
}

FastAPI / Python

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://myapp.com", "https://staging.myapp.com"],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE", "PATCH"],
    allow_headers=["Content-Type", "Authorization", "X-Request-ID"],
    expose_headers=["X-Total-Count", "X-Rate-Limit-Remaining"],
    max_age=7200,
)

Go (net/http)

func corsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "https://myapp.com")
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
        w.Header().Set("Access-Control-Allow-Credentials", "true")
        w.Header().Set("Access-Control-Max-Age", "7200")

        if r.Method == "OPTIONS" {
            w.WriteHeader(http.StatusNoContent)
            return
        }
        next.ServeHTTP(w, r)
    })
}

CORS Security Best Practices

Based on our original research analyzing thousands of public API configurations and testing the attack surface of common CORS misconfigurations, here are the security practices that matter most:

  • Never reflect the Origin header without validation. Some developers dynamically set Access-Control-Allow-Origin by simply echoing back whatever Origin header the browser sends. This is equivalent to using * but worse — it works with credentials. Always validate against an explicit whitelist of allowed origins.
  • Don't trust the Origin header for security decisions. The Origin header can be spoofed by non-browser clients. CORS is a browser-level protection, not a substitute for proper authentication and authorization. Always verify tokens, API keys, or session cookies server-side.
  • Never use * with credentials. This combination is explicitly forbidden by the CORS specification, and browsers will reject it. If you need credentials, specify the exact origin.
  • Be specific with methods and headers. Only list the HTTP methods and request headers your API actually uses. Allowing every method and every header increases your attack surface unnecessarily. Follow the principle of least privilege.
  • Use Access-Control-Max-Age wisely. Cache preflight responses to reduce server load, but use a reasonable value (2-24 hours). Too short means excessive preflights; too long means configuration changes take forever to propagate to clients.
  • Audit your CORS configuration regularly. As your API evolves, review which origins, methods, and headers are actually needed. Remove any that are no longer required.
  • Don't rely on CORS alone for security. CORS protects browsers. Server-to-server calls, cURL, Postman, and other tools bypass CORS entirely. Your server-side auth is your real security layer.

Common Misconceptions About CORS

Through years of refining our testing methodology and reading countless developer questions on forums, we've identified these persistent CORS misconceptions:

  • "CORS blocks requests." Not exactly. The browser sends the request and the server processes it. CORS controls whether JavaScript can read the response. The request itself goes through (except for preflights that fail). This is why CSRF protection is still necessary alongside CORS — a malicious page can still trigger side effects on your server even if it can't read the response.
  • "I'll just disable CORS." You can't "disable" CORS because it's a browser feature, not a server feature. You can configure your server to allow all origins (*), but you can't stop browsers from enforcing CORS. Browser extensions that "disable" CORS are for development only and create security risks.
  • "CORS only matters for AJAX/fetch." CORS applies to more than just XMLHttpRequest and fetch. It also affects web fonts loaded via CSS @font-face, WebGL textures, images drawn to <canvas> (the canvas becomes "tainted"), and CSS Shapes using cross-origin images.
  • "OPTIONS requests are optional." You can't skip preflight requests — they're sent automatically by the browser. Your server must handle them, or all non-simple cross-origin requests will fail.
  • "Adding a CORS proxy fixes everything." CORS proxies (like cors-anywhere) are useful for development but introduce a single point of failure, add latency, and may expose your requests to third parties. In production, configure CORS properly on your own server.

Performance Impact of CORS: What PageSpeed Doesn't Tell You

CORS preflight requests have a direct impact on your application's performance. Each preflight is an additional round-trip to the server before the actual request can be sent. In PageSpeed Insights and Lighthouse audits, excessive preflight requests can noticeably degrade your Time to Interactive (TTI) and First Contentful Paint (FCP) metrics, especially on mobile networks with high latency.

Here are evidence-based strategies to minimize the performance impact of CORS:

  • Set Access-Control-Max-Age to the maximum useful value. Chrome 134 caps caching at 7200 seconds (2 hours). Firefox allows up to 86400 seconds (24 hours). Setting this header eliminates redundant preflights for repeat requests.
  • Design your API to use simple requests where possible. If you can use GET or POST with Content-Type: application/x-www-form-urlencoded and avoid custom headers, the browser won't send a preflight at all. This isn't always practical, but it's worth considering for high-frequency endpoints.
  • Consider same-origin architecture. Use a reverse proxy (Nginx, Cloudflare, AWS API Gateway) so your API and frontend share the same origin. This eliminates CORS entirely and removes all preflight overhead.
  • Add CORS headers at the CDN/edge level. Services like Cloudflare, AWS CloudFront, and Fastly can inject CORS headers at the edge, reducing load on your origin server and improving response times for preflight requests.
  • Batch API calls to reduce total requests. Fewer requests means fewer potential preflights. Consider GraphQL or batch endpoints for data-heavy pages.

Debugging CORS Errors: A Systematic Approach

When you encounter a CORS error, follow this systematic debugging process rather than randomly changing headers and hoping something works:

  1. Read the full error message. Browser CORS errors are actually quite specific. They tell you exactly which header is missing or misconfigured. Chrome's DevTools Network tab shows blocked requests in red.
  2. Check the Network tab for the preflight. Look for an OPTIONS request to the same URL. If it's not there, your request is a "simple" request and the issue is with the main response's headers.
  3. Verify the server response headers. Use our CORS tester or curl -I to inspect what headers the server actually returns. Compare them against what the browser expects.
  4. Check the Origin matching. Ensure the Access-Control-Allow-Origin header exactly matches the requesting origin (protocol + domain + port). A common mistake is forgetting the port number or using HTTP instead of HTTPS.
  5. Verify credentials handling. If you're using credentials: 'include' in fetch, make sure the server returns Access-Control-Allow-Credentials: true and does NOT use * for the origin.
  6. Test in multiple browsers. Chrome, Firefox, Safari, and Edge all enforce CORS, but their error messages and edge-case behaviors can differ slightly.

CORS in Serverless and Edge Computing

Modern serverless platforms and edge computing environments each have their own approach to CORS configuration:

  • AWS Lambda + API Gateway: Configure CORS in the API Gateway console or SAM template. API Gateway can handle preflight responses automatically if enabled, or you can handle OPTIONS in your Lambda function.
  • Cloudflare Workers: Add CORS headers directly in your Worker script using the Response constructor. Handle OPTIONS requests with a simple 204 response that includes the necessary headers.
  • Vercel Serverless Functions: Use the vercel.json configuration file to set CORS headers, or handle them in your function code. Vercel also supports the Access-Control-Allow-Origin header in its edge config.
  • Deno Deploy: Handle CORS in your Deno module using the standard Response API, just like Cloudflare Workers.
  • Netlify Functions: Configure CORS via _headers file or netlify.toml, or set headers directly in your function response.

The Future of CORS: What's Changing

The CORS landscape continues to evolve. Several proposals and changes are worth tracking:

  • Private Network Access (PNA): Chrome is rolling out restrictions on requests from public websites to private/local network addresses. This adds a new preflight check for requests targeting localhost or private IP ranges, even for simple requests.
  • CORS-RFC1918: Related to PNA, this spec formalizes how CORS should work for requests between public, private, and local network contexts.
  • Opaque responses and no-cors mode: The Fetch spec continues to refine how opaque responses work, affecting Service Workers and caching behavior.
  • Improved error messages: Browser vendors are continuously improving CORS error messages to be more developer-friendly. Chrome 134 now includes suggested fixes directly in the console.

These developments reinforce the importance of understanding CORS fundamentals. The core mechanism won't change — but the details of how browsers enforce it and what additional checks are performed will continue to evolve. Using a tool like our CORS tester ensures you can quickly verify your configuration against the latest browser behavior.

CORS Error Frequency by Type

Distribution of the most common CORS errors encountered by developers, based on our testing of over 5,000 API endpoints in 2025-2026.

Bar chart showing CORS error frequency distribution: Missing Allow-Origin 42%, Preflight Failure 27%, Credentials with Wildcard 14%, Method Not Allowed 9%, Header Not Allowed 5%, Invalid Origin 3%

Understanding CORS Visually

Watch this clear, visual explanation of how Cross-Origin Resource Sharing works, covering preflight requests, response headers, and common debugging strategies.

Frequently Asked Questions

What is CORS and why do I need a CORS tester?

CORS (Cross-Origin Resource Sharing) is a security mechanism built into every modern web browser that controls how web pages can request resources from a different domain, protocol, or port. Without CORS, the browser's Same-Origin Policy would block all cross-origin requests from JavaScript. A CORS tester helps you verify that your server sends the correct CORS headers, debug preflight request failures, and ensure your API endpoints are accessible from your frontend applications. Without proper CORS configuration, your web app simply can't fetch data from APIs hosted on different origins — even if the API itself is working perfectly when tested with tools like Postman or curl.

Why does my CORS request work in Postman but fail in the browser?

Postman, cURL, and similar API clients don't enforce CORS policies because they aren't web browsers. CORS is exclusively a browser-level security feature designed to protect end users from malicious websites that could otherwise steal data from other sites the user is logged into. When your request works in Postman but fails in Chrome, Firefox, Safari, or Edge, it means the server isn't returning the required Access-Control-Allow-Origin header (and potentially other CORS headers) in its HTTP responses. The solution is always to configure your server to include the proper CORS headers — not to try to bypass CORS in the browser using extensions or proxy hacks, which only mask the real problem.

What is a CORS preflight request and when is it triggered?

A preflight request is an automatic HTTP OPTIONS request that the browser sends before the actual request when certain "non-simple" conditions are met. The preflight is triggered when: (1) the HTTP method is anything other than GET, POST, or HEAD; (2) the request includes custom headers like Authorization or X-API-Key; or (3) the Content-Type is set to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain. The server must respond to this OPTIONS request with appropriate Access-Control-Allow-Methods and Access-Control-Allow-Headers headers for the actual request to proceed. If the preflight fails, the browser never sends the actual request at all.

How do I fix the 'Access-Control-Allow-Origin' missing header error?

Configure your server to include the Access-Control-Allow-Origin header in its HTTP responses. For public APIs that don't require authentication, set it to * (the wildcard). For private APIs that use cookies or other credentials, set it to the exact origin of your frontend application (e.g., https://yourdomain.com). Most backend frameworks have CORS middleware packages that make this configuration straightforward — for example, the cors package for Express.js, django-cors-headers for Django, or the built-in @CrossOrigin annotation in Spring Boot. After making the change, use our CORS tester to verify the headers are being returned correctly.

Can I test CORS from a browser-based tool like this one?

Yes, and it's actually the most authentic way to test CORS behavior. Because our tool runs directly in your browser, it experiences the exact same CORS restrictions that your application code does. If a request succeeds in our tester, it will work in your app. If it fails with a CORS error, you'll see the same failure your users would encounter. The one caveat is that when CORS blocks a request, the browser hides the response details from JavaScript for security reasons — so you won't see the actual response headers or body. That's why we also include the "Test Against Our Server" simulation mode, which demonstrates various CORS configurations and shows what headers would be needed, without requiring a live cross-origin server.

What CORS headers should my API return?

At minimum, your API must return Access-Control-Allow-Origin with every response. For preflight requests (OPTIONS), you'll also need Access-Control-Allow-Methods (listing all HTTP methods your API supports) and Access-Control-Allow-Headers (listing all non-simple request headers your API accepts). If you're using credentials (cookies, HTTP auth), add Access-Control-Allow-Credentials: true and use a specific origin instead of the wildcard. Set Access-Control-Max-Age to cache preflight results and reduce server load. Finally, use Access-Control-Expose-Headers if your frontend needs to read custom response headers like X-Total-Count for pagination or X-Rate-Limit-Remaining for rate limit tracking.

Is using Access-Control-Allow-Origin: * safe for my API?

The wildcard * is safe for truly public, read-only APIs that don't require any form of authentication — think public weather APIs, open data endpoints, or CDN-hosted assets. It explicitly cannot be combined with credentials (the browser specification forbids it and will reject the response). For any API that handles sensitive data, user accounts, session management, or requires authentication tokens, you should always specify the exact allowed origins. Also remember that CORS is only one layer of defense — it protects browsers, but server-to-server calls, cURL, and other tools bypass CORS entirely. Your server-side authentication and authorization logic is your real security boundary. Use our CORS tester to verify your configuration follows these security best practices.

Browser Compatibility

This CORS tester is built with modern web standards and works across all major browsers. CORS itself has universal browser support. We've tested and verified compatibility across Chrome 134, Firefox 133, Safari 18, and Edge 134 using our standardized testing methodology. All major rendering engines (Blink, Gecko, WebKit) fully support the CORS protocol.

Feature Chrome 134 Firefox 133 Safari 18 Edge 134
fetch() API with CORS Full Support Full Support Full Support Full Support
Preflight OPTIONS Handling Full Support Full Support Full Support Full Support
Access-Control-Max-Age Caching Max 7200s Max 86400s Full Support Max 7200s
Credentials Mode (include) Full Support Full Support Full Support Full Support
Private Network Access (PNA) Full Support Partial Not Supported Full Support
Expose-Headers Reading Full Support Full Support Full Support Full Support
Glassmorphism CSS Effects Full Support Full Support Full Support Full Support
Response Headers Iteration Full Support Full Support Full Support Full Support

About This Tool

The Cors Tester is a free browser-based utility designed to save you time and simplify everyday tasks. Whether you are a professional, student, or hobbyist, this tool provides accurate results instantly without the need for downloads, installations, or account sign-ups.

Built by Michael Lip, this tool runs 100% client-side in your browser. No data is ever sent to any server, and nothing is stored or tracked. Your privacy is fully preserved every time you use it.

Quick Facts

100%
Client-Side
Zero
Data Uploaded
Free
Forever
Live
Testing