api: YAML JSON TOON Database
version: 1.0.0
format: yaml
dataset:
  id: 2402
  slug: http-cors-guide
  title: CORS (Cross-Origin Resource Sharing) Guide
  description: "Complete CORS reference: preflight requests, Access-Control headers, credentials, wildcard policies, and common pitfalls."
  summary: "A guide to Cross-Origin Resource Sharing: the Access-Control response and request headers, what makes a request 'simple', and the common mistakes, such as combining a wildcard origin with credentials or forgetting to answer preflight requests."
  use_when:
    - You are debugging a browser CORS error.
    - You are configuring an API for browser clients on another origin.
  caveats:
    - CORS is enforced by browsers, not servers; non-browser clients are not subject to it.
    - A permissive configuration can expose authenticated APIs to any site; allow only the origins you need.
  related:
    - http-request-headers
    - http-response-headers
    - common-vulnerabilities-owasp
    - browser-web-apis-reference
  entry_count: 14
  fields:
    - section: headers
      field: header
      type: string
      example: Access-Control-Allow-Origin
    - section: headers
      field: direction
      type: string
      example: Response
    - section: headers
      field: description
      type: string
      example: Specifies which origins can access the resource
    - section: headers
      field: example
      type: string
      example: "Access-Control-Allow-Origin: https://example.co…"
    - section: headers
      field: notes
      type: string
      example: Cannot use * with credentials; must echo specif…
    - section: simple_requests
      field: "*"
      type: object
      example: "{description,conditions,notes}"
    - section: common_mistakes
      field: mistake
      type: string
      example: Using * with credentials
    - section: common_mistakes
      field: fix
      type: string
      example: Echo the specific Origin header value instead o…
  category: HTTP Status Codes
  category_slug: http-status-codes
  tags: http,cors,cross-origin,security,preflight,access-control,same-origin
  view_count: 35
  created_at: 1778695229
  updated_at: 1778695229
data:
  headers:
    - header: Access-Control-Allow-Origin
      direction: Response
      description: Specifies which origins can access the resource
      example: "Access-Control-Allow-Origin: https://example.com OR * (wildcard)"
      notes: Cannot use * with credentials; must echo specific origin for credentialed requests
    - header: Access-Control-Allow-Methods
      direction: Response (preflight)
      description: Allowed HTTP methods for the resource
      example: "Access-Control-Allow-Methods: GET, POST, DELETE"
      notes: Returned in response to OPTIONS preflight; list only what's actually supported
    - header: Access-Control-Allow-Headers
      direction: Response (preflight)
      description: Allowed custom headers in requests
      example: "Access-Control-Allow-Headers: Content-Type, Authorization, X-Custom-Header"
      notes: Must include all non-simple headers the client needs to send
    - header: Access-Control-Expose-Headers
      direction: Response
      description: Headers the browser is allowed to expose to client-side code
      example: "Access-Control-Expose-Headers: X-Total-Count, X-Page-Count"
      notes: By default, only Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma are exposed
    - header: Access-Control-Allow-Credentials
      direction: Response
      description: Whether cookies/auth are included in cross-origin requests
      example: "Access-Control-Allow-Credentials: true"
      notes: Requires Access-Control-Allow-Origin to be a specific origin (not *)
    - header: Access-Control-Max-Age
      direction: Response (preflight)
      description: How long (seconds) preflight result can be cached
      example: "Access-Control-Max-Age: 86400"
      notes: "Reduces preflight overhead; browsers cap this (Chrome: 2h, Firefox: 24h)"
    - header: Origin
      direction: Request
      description: Client sends the origin making the request
      example: "Origin: https://example.com"
      notes: Sent with all CORS requests; server uses this to decide whether to allow
    - header: Access-Control-Request-Method
      direction: Request (preflight)
      description: Method that will be used in the actual request
      example: "Access-Control-Request-Method: DELETE"
      notes: Sent in OPTIONS preflight to ask server if method is allowed
    - header: Access-Control-Request-Headers
      direction: Request (preflight)
      description: Headers that will be used in the actual request
      example: "Access-Control-Request-Headers: Content-Type, Authorization"
      notes: Sent in OPTIONS preflight to ask server if headers are allowed
  simple_requests:
    description: Requests that don't trigger preflight (OPTIONS)
    conditions:
      - Method is GET, HEAD, or POST only
      - "Headers are only: Accept, Accept-Language, Content-Language, Content-Type (with simple values)"
      - Content-Type is application/x-www-form-urlencoded, multipart/form-data, or text/plain
      - No ReadableStream in request body
    notes: POST with application/json triggers preflight! Use application/x-www-form-urlencoded for simple POST.
  common_mistakes:
    - mistake: Using * with credentials
      fix: Echo the specific Origin header value instead of *
    - mistake: Forgetting to handle OPTIONS method
      fix: Add OPTIONS handler that returns CORS headers for preflight
    - mistake: Not caching preflight responses
      fix: Add Access-Control-Max-Age to preflight responses
    - mistake: Exposing custom headers without Access-Control-Expose-Headers
      fix: Add Access-Control-Expose-Headers for any custom response headers client needs
    - mistake: Returning CORS headers on all responses including errors
      fix: Ensure CORS headers are present on 4xx/5xx responses too
