CORS preflight

CORS 사전 요청

Before certain cross-origin requests, the browser checks server permission with OPTIONS.

···
html
<div class="n-demo"><div class="n-head"><strong>CORS GATE</strong><span>LIVE TRACE</span></div><div class="n-stage"><div class="cors-flow"><div class="n-box mono" id="c0">OPTIONS /api</div><div class="cors-gate" id="c1">ALLOW?</div><div class="n-box mono" id="c2">POST /api</div><div class="cors-note" id="c3">checking policy</div></div></div><div class="n-foot">tap to step · auto replay</div></div>
css
.n-demo{width:min(94vw,760px);height:min(88vh,324px);padding:clamp(9px,2.2vmin,18px);border:1px solid var(--line);border-radius:13px;background:var(--surface);display:flex;flex-direction:column;gap:clamp(5px,1.3vmin,10px);font:600 clamp(12px,2.4vmin,16px)/1.3 "Pretendard Variable",Pretendard,-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo",sans-serif;overflow:hidden}.n-head,.n-foot{display:flex;justify-content:space-between;align-items:center;color:var(--muted)}.n-head strong{color:var(--accent)}.n-head span,.n-foot{font-size:12px}.n-stage{flex:1;min-height:0;position:relative;display:flex;align-items:center;justify-content:center;gap:clamp(4px,1vmin,10px)}.mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.n-box{padding:clamp(5px,1.5vmin,11px);border:1px solid var(--line);border-radius:8px;background:var(--bg);text-align:center}.n-on{border-color:var(--accent)!important;color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 12%,var(--surface))!important}.n-muted{color:var(--muted)}@media(max-width:400px){.n-head span{display:none}}.cors-flow{width:95%;display:grid;grid-template-columns:1fr .8fr 1fr;align-items:center;gap:6px}.cors-gate{border:2px solid var(--line);border-radius:50%;padding:12px 3px;text-align:center}.cors-flow .n-box{padding:9px 2px}.cors-note{grid-column:1/-1;text-align:center;color:var(--muted)}
js
let step=0;function advance(){const notes=['send preflight','allow origin + method','send actual request','deny: stop at browser'];for(let i=0;i<3;i++)document.getElementById('c'+i).classList.toggle('n-on',i===Math.min(step,2)&&step!==3);document.getElementById('c3').textContent=notes[step];document.getElementById('c1').textContent=step===3?'DENY':'ALLOW?';step=(step+1)%4}
const clickTarget=document.querySelector('.n-demo');if(clickTarget&&typeof advance==='function'){advance();const timer=setInterval(advance,1050);clickTarget.addEventListener('pointerdown',()=>{clearInterval(timer);advance()})}

For certain cross-origin requests, the browser first sends OPTIONS. It checks the server response for allowed origin, method, and headers before sending the actual request.

In the demo, an allowed preflight leads to POST; a denied one stops at the browser. CORS controls browser access to responses and does not replace server authentication.

When to use

Inspect preflight response headers when a browser blocks a cross-origin API call.

Open as page ↗