1"use strict";(self.webpackChunkbeeceptor_docs=self.webpackChunkbeeceptor_docs||[]).push([["338"],{83654(e,s,r){r.r(s),r.d(s,{metadata:()=>n,default:()=>h,frontMatter:()=>o,contentTitle:()=>d,toc:()=>l,assets:()=>c});var n=JSON.parse('{"id":"web-basics/cors","title":"CORS Headers","description":"Understand CORS headers and their importance in web security. Learn how to implement CORS in Java, JavaScript, Go, and Python frameworks, with best practices and detailed server-side guidelines.","source":"@site/docs/web-basics/cors.md","sourceDirName":"web-basics","slug":"/concepts/cors","permalink":"/docs/concepts/cors","draft":false,"unlisted":false,"tags":[{"inline":true,"label":"Learnings","permalink":"/docs/tags/learnings"}],"version":"current","sidebarPosition":9,"frontMatter":{"id":"cors","slug":"/concepts/cors","title":"CORS Headers","description":"Understand CORS headers and their importance in web security. Learn how to implement CORS in Java, JavaScript, Go, and Python frameworks, with best practices and detailed server-side guidelines.","sidebar_label":"CORS Headers","sidebar_position":9,"tags":["Learnings"]},"sidebar":"tutorialSidebar","previous":{"title":"HTTP Status - 400 vs 422","permalink":"/docs/concepts/400-vs-422"},"next":{"title":"CRUD Operations","permalink":"/docs/concepts/crud-operations-and-apis"}}'),i=r(74848),t=r(28453);let o={id:"cors",slug:"/concepts/cors",title:"CORS Headers",description:"Understand CORS headers and their importance in web security. Learn how to implement CORS in Java, JavaScript, Go, and Python frameworks, with best practices and detailed server-side guidelines.",sidebar_label:"CORS Headers",sidebar_position:9,tags:["Learnings"]},d,c={},l=[{value:"What is CORS?",id:"what-is-cors",level:2},{value:"Why Is CORS Required?",id:"why-is-cors-required",level:2},{value:"How CORS Works",id:"how-cors-works",level:2},{value:"CORS HTTP Headers",id:"cors-http-headers",level:2},{value:"Example",id:"example",level:3},{value:"CORS Request Headers",id:"cors-request-headers",level:3},{value:"CORS Response Headers",id:"cors-response-headers",level:3},{value:"Server-Side Implementation of CORS",id:"server-side-implementation-of-cors",level:2},{value:"Implementing CORS on the Client-Side",id:"implementing-cors-on-the-client-side",level:2},{value:"Further Reading",id:"further-reading",level:2}];function a(e){let s={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components},{Head:r}=s;return r||function(e,s){throw Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Head",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(r,{children:[(0,i.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,i.jsx)("meta",{name:"twitter:site",content:"@beeceptor"}),(0,i.jsx)("meta",{name:"twitter:creator",content:"@beeceptor"}),(0,i.jsx)("meta",{property:"og:title",content:"CORS Headers"}),(0,i.jsx)("meta",{property:"og:description",content:"Understand CORS headers and their importance in web security. Learn how to implement CORS in Java, JavaScript, Go, and Python frameworks, with best practices and detailed server-side guidelines."}),(0,i.jsx)("meta",{name:"twitter:image",content:"https://beeceptor.com/docs/img/page-preview/cors.png"}),(0,i.jsx)("meta",{property:"og:image",content:"https://beeceptor.com/docs/img/page-preview/cors.png"})]}),"\n",(0,i.jsx)(s.h2,{id:"what-is-cors",children:"What is CORS?"}),"\n",(0,i.jsx)(s.p,{children:'Cross-Origin Resource Sharing (CORS) is a security feature implemented in browsers to control access to resources located outside of a given domain. It is a mechanism that allows or denies requests for resources from a web page served by one domain (the "origin") to a server at a different domain.'}),"\n",(0,i.jsx)(s.h2,{id:"why-is-cors-required",children:"Why Is CORS Required?"}),"\n",(0,i.jsx)(s.p,{children:"Traditionally, web browsers implement a security model known as the Same-Origin Policy (SOP). SOP restricts web pages from making requests to a different domain than the one that served the web page. While this policy prevents malicious scripts from interacting with resources from another domain, it also limits legitimate cross-origin requests essential for modern web applications."}),"\n",(0,i.jsx)(s.p,{children:"CORS was introduced as a solution to safely override the SOP under certain conditions, allowing controlled cross-origin requests, thus enabling functionalities like APIs, CDNs, and external libraries to work seamlessly across domains."}),"\n",(0,i.jsx)(s.h2,{id:"how-cors-works",children:"How CORS Works"}),"\n",(0,i.jsxs)(s.p,{children:["When a web application makes a cross-origin HTTP request, the browser automatically adds an ",(0,i.jsx)(s.code,{children:"Origin"})," header to the request, indicating the domain of the web page. The server then decides whether to accept or reject this request based on its CORS policy."]}),"\n",(0,i.jsxs)(s.p,{children:["If the server allows the request, it responds with the appropriate CORS ",(0,i.jsx)(s.a,{href:"/concepts/http-headers/",children:"HTTP headers"}),", such as ",(0,i.jsx)(s.code,{children:"Access-Control-Allow-Origin"}),", indicating which origins are permitted. The browser then permits the web page to access the response if the server's response matches the request's origin."]}),"\n",(0,i.jsx)(s.p,{children:"During a CORS request,"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["the browser first sends a preflight request (",(0,i.jsx)(s.code,{children:"OPTIONS"})," method) with the ",(0,i.jsx)(s.code,{children:"Access-Control-Request-Method"})," and ",(0,i.jsx)(s.code,{children:"Access-Control-Request-Headers"})," (optional) to check if the server allows the actual request."]}),"\n",(0,i.jsxs)(s.li,{children:["the server responds with the ",(0,i.jsx)(s.code,{children:"Access-Control-Allow-Origin"}),", ",(0,i.jsx)(s.code,{children:"Access-Control-Allow-Credentials"})," (optional), and ",(0,i.jsx)(s.code,{children:"Access-Control-Expose-Headers"})," (optional) headers, indicating permissions and accessible data."]}),"\n",(0,i.jsx)(s.li,{children:"if the preflight is successful, the browser sends the actual request with the allowed method and headers."}),"\n"]}),"\n",(0,i.jsx)(s.mermaid,{value:"sequenceDiagram\n participant Client as Web Browser<br>(Client)\n participant Server as API Server\n\n Note over Client,Server: Pre-flight request to query the web-server\n\n Client->>+Server: OPTIONS /resource<br>Headers: `Origin`, `Access-Control-Request-Method`, `Access-Control-Request-Headers`\n Server--\x3e>-Client: HTTP 200 OK<br>Headers: `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, <br>`Access-Control-Allow-Headers`, `Access-Control-Max-Age`\n\n Note over Client,Server: Browser evaluates response:<br>Proceeds if headers are valid. Blocks request if headers are missing/invalid\n\n Client->>+Server: POST /resource<br>Headers: `Origin`, `Content-Type`\n Server--\x3e>-Client: HTTP 200 OK<br>Headers: `Access-Control-Allow-Origin`\n"}),"\n",(0,i.jsx)(s.h2,{id:"cors-http-headers",children:"CORS HTTP Headers"}),"\n",(0,i.jsx)(s.h3,{id:"example",children:"Example"}),"\n",(0,i.jsxs)(s.p,{children:["Let's take a practical scenario. Here a client application hosted at ",(0,i.jsx)(s.code,{children:"https://example-client.com"})," sends a cross-origin POST request to ",(0,i.jsx)(s.code,{children:"https://api.example-server.com"})," with credentials and a custom header (X-Auth-Token)."]}),"\n",(0,i.jsx)(s.p,{children:"Request Headers:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-yaml",children:"POST /resource HTTP/1.1\nHost: api.example-server.com\nOrigin: https://example-client.com\nContent-Type: application/json\nX-Auth-Token: abc123\n"})}),"\n",(0,i.jsx)(s.p,{children:"Server Response Headers:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-yaml",children:"HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: https://example-client.com\nAccess-Control-Allow-Credentials: true\nAccess-Control-Expose-Headers: X-Custom-Header\nContent-Length: 123\n"})}),"\n",(0,i.jsxs)(s.p,{children:["In this example, the server permits the client from ",(0,i.jsx)(s.code,{children:"https://example-client.com"})," to access the resource, allowing credentials to be sent and exposing the custom header ",(0,i.jsx)(s.code,{children:"X-Custom-Header"}),"."]}),"\n",(0,i.jsx)(s.h3,{id:"cors-request-headers",children:"CORS Request Headers"}),"\n",(0,i.jsx)(s.p,{children:"The client/browser sends the following headers to the server to identify the website initiating the API call."}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Header Name"}),(0,i.jsx)(s.th,{children:"Purpose"}),(0,i.jsx)(s.th,{children:"Example Value"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Origin"})}),(0,i.jsx)(s.td,{children:"Identifies the origin of the request (originating website)."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"https://example-client.com"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Access-Control-Request-Method"})}),(0,i.jsx)(s.td,{children:"Informs the server about the HTTP method intended for the actual request during a preflight request."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"POST"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Access-Control-Request-Headers"})}),(0,i.jsx)(s.td,{children:"Lists custom request headers the browser plans to send with the actual request during a preflight request."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Content-Type, X-Auth-Token"})})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"cors-response-headers",children:"CORS Response Headers"}),"\n",(0,i.jsx)(s.p,{children:"The server responds to the original (or pre-flight) request with the following headers, specifying what is permitted. This allows the web-browser to determine whether to proceed with the cross-domain call."}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Header Name"}),(0,i.jsx)(s.th,{children:"Purpose"}),(0,i.jsx)(s.th,{children:"Example Value"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Vary"})}),(0,i.jsxs)(s.td,{children:["Indicates headers that influence the response, potentially including ",(0,i.jsx)(s.code,{children:"Origin"})," (relevant for CORS)."]}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Origin"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Access-Control-Allow-Origin"})}),(0,i.jsx)(s.td,{children:"Specifies which origins are permitted to access the resource."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"https://example-client.com"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Access-Control-Allow-Credentials"})}),(0,i.jsx)(s.td,{children:"Specifies whether credentials (cookies, authorization headers) are allowed in cross-origin requests."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"true"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Access-Control-Expose-Headers"})}),(0,i.jsx)(s.td,{children:"Lists custom response headers that should be accessible to client-side JavaScript."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"X-Custom-Header, Content-Length"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Access-Control-Allow-Methods"})}),(0,i.jsx)(s.td,{children:"Specifies the HTTP methods that are permitted when accessing the resource in cross-origin requests."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"GET, POST, PUT, DELETE"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Access-Control-Allow-Headers"})}),(0,i.jsx)(s.td,{children:"Lists the HTTP headers that can be used during the actual request."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Content-Type, X-Auth-Token"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Access-Control-Max-Age"})}),(0,i.jsx)(s.td,{children:"Specifies how long the results of a preflight request can be cached by the browser."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"3600"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"Timing-Allow-Origin"})}),(0,i.jsx)(s.td,{children:"Specifies origins that are allowed to view timing information via the Resource Timing API."}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"https://example-client.com"})})]})]})]}),"\n",(0,i.jsxs)(s.p,{children:["The ",(0,i.jsx)(s.code,{children:"Origin"})," header (in the request) and ",(0,i.jsx)(s.code,{children:"Vary"})," header (in the response) plays a role in CORS as well, though they are not strictly CORS-specific headers."]}),"\n",(0,i.jsx)(s.h2,{id:"server-side-implementation-of-cors",children:"Server-Side Implementation of CORS"}),"\n",(0,i.jsxs)(s.p,{children:["CORS is managed by the web server that provides the API. The server determines which origins or domains are permitted to send AJAX or ",(0,i.jsx)(s.code,{children:"XMLHttpRequest"})," calls."]}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Configure the server to include CORS headers, such as ",(0,i.jsx)(s.code,{children:"Access-Control-Allow-Origin"}),", in its responses."]}),"\n",(0,i.jsx)(s.li,{children:"Define the allowed origins, which can be a specific domain, multiple domains, or a wildcard (*) to permit all domains."}),"\n",(0,i.jsxs)(s.li,{children:["Specify which ",(0,i.jsx)(s.a,{href:"/concepts/http-verbs/",children:"HTTP methods (GET, POST, etc.)"})," and headers are permitted."]}),"\n",(0,i.jsxs)(s.li,{children:["Handle preflight requests. Preflight requests use the ",(0,i.jsx)(s.code,{children:"OPTIONS"})," method and are sent by the browser to determine if the actual request is safe to send."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"Various frameworks in Java, JavaScript, Go, and Python offer built-in supp
1ort or plugins for easily implementing CORS on the server side."}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["In ",(0,i.jsx)(s.strong,{children:"Java"}),", frameworks like Spring Boot and Jersey are prevalent. Spring Boot facilitates CORS through annotations such as @CrossOrigin and global configurations, while Jersey uses response filters to add CORS headers."]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"JavaScript"})," (Node.js) frameworks such as Express.js, Hapi.js, and Koa.js each have their approaches. Express.js utilizes the cors middleware, Hapi.js offers plugins like hapi-cors-headers, and Koa.js supports CORS through third-party middleware."]}),"\n",(0,i.jsxs)(s.li,{children:["For ",(0,i.jsx)(s.strong,{children:"Go (Golang)"}),", frameworks like Gin and Echo provide in-built or middleware support for CORS. Gin includes built-in middleware for CORS configuration, whereas Echo uses a dedicated middleware for the same purpose."]}),"\n",(0,i.jsxs)(s.li,{children:["In the ",(0,i.jsx)(s.strong,{children:"Python"})," ecosystem, Django and Flask are popular choices. Django's django-cors-headers middleware and Flask's Flask-CORS extension allow developers to control CORS headers with ease. FastAPI, a newer Python framework, also offers built-in support for CORS."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"implementing-cors-on-the-client-side",children:"Implementing CORS on the Client-Side"}),"\n",(0,i.jsx)(s.p,{children:"CORS is primarily a server-side mechanism enforced by trusted web browsers to ensure security. Browsers adhere to CORS policies, while non-browser clients like Postman, Bruno, or custom code in Java, Python, or Node.js ignore CORS headers entirely. Here are some key points and best practices for client-side handling of CORS:"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Making Cross-Origin Requests:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Use JavaScript's XMLHttpRequest or the modern Fetch API for making cross-origin requests."}),"\n",(0,i.jsx)(s.li,{children:"Ensure you specify the appropriate HTTP methods, headers, and credentials (if needed) in your requests."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Handling CORS Errors:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"CORS errors typically appear as JavaScript console errors indicating that the requested resource's origin is not permitted."}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Implement proper error handling in your code to gracefully deal with these errors. For example:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-javascript",children:"fetch('https://example.com/api', { method: 'GET' })\n.then(response => {\n if (!response.ok) throw new Error('CORS error or other issue');\n return response.json();\n})\n.catch(error => console.error('Error:', error));\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Proxy Server for Restricted APIs:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"If the API server does not allow requests from your domain, set up an HTTP proxy on your server to route client requests to the target API."}),"\n",(0,i.jsxs)(s.li,{children:["This ",(0,i.jsx)(s.a,{href:"/bypassing-cors/",children:"effectively bypasses CORS restrictions"})," by making the request from your server, not the browser. Example:","\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-rust",children:"Client -> ProxyServer -> TargetAPI\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Understanding Non-Browser Clients:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Tools and libraries like Postman, Curl, and custom backend scripts do not enforce CORS because CORS is a browser-specific security mechanism. This means you can directly make requests from these clients without encountering CORS restrictions."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Request Configuration Tips:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Use the mode: 'cors' option in Fetch API for CORS requests. For example:"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-javascript",children:"fetch('https://example.com/api', { \n method: 'GET', \n mode: 'cors' \n});\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Set credentials: 'include' if you need to send cookies or HTTP authentication headers with cross-origin requests."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.strong,{children:"Important Notes:"})}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"CORS is designed to protect end-users by enforcing origin restrictions in web browsers. If an API does not explicitly allow your origin, you cannot override these restrictions directly from the client side."}),"\n",(0,i.jsx)(s.li,{children:"Always validate server responses to ensure that critical data is not exposed or misused, even when using a proxy."}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"further-reading",children:"Further Reading"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS at MDN"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://fetch.spec.whatwg.org/#cors-protocol",children:"Fetch - the specification"})}),"\n"]})]})}function h(e={}){let{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453(e,s,r){r.d(s,{R:()=>o,x:()=>d});var n=r(96540);let i={},t=n.createContext(i);function o(e){let s=n.useContext(t);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.