Summary
"Simple" requests skip preflight; non-simple methods, custom headers, or non-simple content-types trigger OPTIONS. Server must echo Access-Control-Allow-Origin and allowed methods/headers. Credentials require explicit Access-Control-Allow-Credentials: true and non-wildcard origin. Debug with Network tab — failed preflight never reaches your handler. See also 5.9 SameSite cookie modes, 6.9 CORS preflight internals.
Code example
await fetch('https://api.example.com/data', {
method: 'PUT',
headers: { 'Content-Type': 'application/json', 'X-Custom': '1' },
credentials: 'include',
});
// Browser sends OPTIONS preflight before PUT
Key points
- "Simple" requests skip preflight; non-simple methods, custom headers, or non-simple content-types trigger
OPTIONS. - Server must echo
Access-Control-Allow-Originand allowed methods/headers. - Credentials require explicit
Access-Control-Allow-Credentials: trueand non-wildcard origin. - Debug with Network tab — failed preflight never reaches your handler.
- See also 5.9 SameSite cookie modes, 6.9 CORS preflight internals.