Request header
> Sec-Fetch-Mode: navigateSec-Fetch-Mode Header: Values and Server Use
Sec-Fetch-Mode reports the request mode: navigate, cors, no-cors, same-origin or websocket. What sets each value and how servers use it.
- Direction
- Request
- Category
- Security
- JS can set it
- No: forbidden header name
On this page
TL;DR:
Sec-Fetch-Modecarries the Fetch API request mode for the request:navigatefor page loads,corsfor ordinaryfetch()and XHR,no-corsfor embedded resources like images and scripts,same-origin, orwebsocket. Pair it with Sec-Fetch-Site to tell a user opening a page from a hostile page loading your endpoint.
Values
GET /report.pdf HTTP/1.1
Host: example.com
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
| Value | What produces it |
|---|---|
navigate | A navigation between documents: link click, address bar, form submission, location.href = ..., and iframe loads. |
cors | A request that follows the CORS protocol: the default for fetch() and XMLHttpRequest, and <script crossorigin>, <img crossorigin> and similar. |
no-cors | A request the page cannot read the response of: plain <img>, <script>, <link rel=stylesheet>, <video> and the like. |
same-origin | A request made with fetch(url, { mode: 'same-origin' }). The browser rejects cross-origin URLs before sending, so servers see this only for same-origin targets. |
websocket | The HTTP request that starts a WebSocket handshake. |
The header is a structured-field token defined in section 2.2 of the W3C Fetch Metadata spec, and it is a forbidden request header: scripts cannot set or change it.
What it is useful for
Mode answers “was this a page load or a sub-request?”. The combination worth enforcing:
navigateplusGET: someone followed a link to you. Safe to serve even whenSec-Fetch-Siteiscross-site.corsorno-corsfromcross-site: another site’s code or markup is pulling your resource. Reject unless you meant to publish it.websocket: browsers do not apply CORS to WebSocket handshakes, so the server has to checkOriginorSec-Fetch-Siteitself to prevent cross-site WebSocket hijacking.
The full policy, with Express and nginx versions, is on the Sec-Fetch-Site page.
Notes
- A default
fetch('/api')sendsSec-Fetch-Mode: corseven to your own origin. Do not infer “cross-origin” fromcors. - Mode is not trustworthy for non-browser clients. curl sends no
Sec-Fetch-*headers, or any value you choose. - Sent only on requests to potentially trustworthy URLs, which means HTTPS and
localhost. - Browser support: Chrome and Edge 76, Firefox 90, Safari 16.4.
Related
Frequently asked questions
What are the possible values of Sec-Fetch-Mode?
Exactly five: cors, navigate, no-cors, same-origin, and websocket. They mirror the mode of the underlying Fetch request. Any other value is not defined by the spec.
What is the difference between Sec-Fetch-Mode no-cors and cors?
cors means the request follows the CORS protocol, so the page can read the response only if the server allows it with Access-Control-Allow-Origin. no-cors is what an img, script, or stylesheet tag produces: the browser loads the resource for rendering but hides the response from scripts. A cross-site no-cors request still reaches your server and still carries cookies when SameSite allows it.
Does fetch() send Sec-Fetch-Mode: cors or same-origin?
A default fetch() has mode cors, so the header is cors even for same-origin URLs. The value same-origin only appears when the caller explicitly passes mode: same-origin, which makes the browser refuse cross-origin URLs.
Which browsers send Sec-Fetch-Mode?
Chrome and Edge 76, Firefox 90, and Safari 16.4. Older browsers and non-browser clients such as curl send nothing, so any server logic must tolerate the header being absent.
Sources
Related
Sec-Fetch-Dest Header: All Values Explained
Sec-Fetch-Dest tells the server where a response will be used: document, iframe, image, script, empty. Full value list and server-side uses.
Sec-Fetch-Site Header: Block Cross-Site Requests
Sec-Fetch-Site says whether a request is same-origin, same-site, cross-site or user-initiated. Resource isolation policy for Express and nginx, plus CSRF use.
Sec-Fetch-User Header: ?1 and User Activation
Sec-Fetch-User is always ?1 and appears only on user-activated navigations, like a link click. When it is absent and why Safari does not send it.
Cross-Origin Resource Sharing (CORS)
Master Cross-Origin Resource Sharing (CORS) for secure cross-origin HTTP requests. Learn preflight requests, headers, credentials, and common error solutions.