Skip to the content.

Module 3: The network edge · Lesson 6 of 7 · 3 min read

Proxy: one origin, and why CORS stops

What a dev proxy and a production reverse proxy actually do, why CORS is granted by the server and never by the request, and what to check in an agent's fix.

Same origin, by construction

Browsers enforce the same-origin policy, where an origin is protocol, domain and port together. An app on localhost:3000 calling an API on localhost:5000 is cross-origin — only the port differs, and that is enough. With a proxy, fetch('/api/users') goes to localhost:3000, the dev server forwards it to :5000 and hands back the response. The browser never applies CORS, because nothing cross-origin happened in the browser.

The doc separates the two kinds. A forward proxy hides the client — a corporate proxy, a VPN. A reverse proxy hides the server — Nginx, Cloudflare. Frontend dev proxies are the reverse kind, and in production a reverse proxy also terminates SSL, balances load, caches and absorbs attacks.

The fix that is not a fix

“Every frontend team hits this in week one and half of them ship the workaround,” the practice quiz begins. Shown a missing Access-Control-Allow-Origin error, an agent will try the request side: add a header to fetch(), switch to XMLHttpRequest, suggest a browser flag. None of it can work. CORS is enforced by the browser and granted by the server, so the fix is on the API, which must allow your origin, or a same-origin proxy.

Two details decide whether the real fix holds:

  • A JSON body with an Authorization header makes the request non-simple, so the browser sends an OPTIONS preflight first. The server must answer it with the allowed origin, methods and headers.
  • Cookies on a cross-origin call need credentials: 'include', Access-Control-Allow-Credentials: true, an explicit origin — the wildcard is rejected with credentials — and SameSite=None; Secure on the cookie. A same-origin proxy turns those four coordinated settings into none.

Mistakes that reach production

The doc’s sharpest one: the proxy in a production build. A dev proxy exists only inside the dev server. The production build is static files, so npm start works and the deployed app returns 404 on every /api call. The others: no changeOrigin, so a backend that validates Host sees localhost:3000 and answers 400 or 403; and unhandled proxy errors such as ERR_CONNECTION_REFUSED with no context. The skill adds: never hardcode backend URLs in frontend code, proxy WebSocket connections too, and set timeouts for slow endpoints.

Review checklist for an agent’s CORS fix

  1. Frontend code calls relative URLs such as /api/users, never http://localhost:5000.
  2. The change is on the API or a proxy, never a header added to the request.
  3. Production has a reverse-proxy rule matching the dev proxy, or the API grants the deployed origin by name.
  4. Credentialed cross-origin calls name an explicit origin, never *.
  5. WebSocket proxying and timeouts are configured where the app needs them.

Encode it, then practise it

Agent Skill: server-proxy The SKILL.md that encodes Proxy for a coding agent. Install it into your agent, or download it for any Agent-Skills-compatible runtime.
npx skills add grvpanchal/elegant --skill server-proxy
Download server-proxy SKILL.md

Practise it

Proxy it or fix CORS?

When a dev proxy is the right tool, when it hides a problem you will meet in production, and what CORS actually protects.

quiz medium server 10 min Solved

Course contents (7 lessons)

Module 1: Routes and containers

  1. Containers: where data meets the UI done
  2. Router: the URL is state too done

Module 2: Rendering strategies

  1. SSR: HTML per request, and the hydration bill done
  2. SSG: render once at build time, cache it right done
  3. App shell: cache the frame, stream the data done

Module 3: The network edge

  1. Proxy: one origin, and why CORS stops done
  2. Session: where tokens live, and what logout means done