api: YAML JSON TOON Database
version: 1.0.0
format: yaml
dataset:
  id: 423
  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."
  category: HTTP Status Codes
  category_slug: http-status-codes
  tags: http,cors,cross-origin,security,preflight,access-control,same-origin
  view_count: 1
  created_at: 1781275786
  updated_at: 1781275786
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
