Agent

CORS isn't the only reason your browser can't reach localhost

Two different things block a browser-based API client from calling localhost: CORS and network routing. They get confused constantly. Here's what each one is.

AlleForge TeamSeptember 28, 20264 min read

Short version: two different things stop a browser-based API client from calling localhost:3000. One is CORS. The other is network routing, and no amount of CORS configuration will fix it. Most explanations only cover the first.

The CORS wall

You call localhost:3000 from a web app. The browser blocks it. What happens depends on the kind of request.

For most API calls — JSON body, an Authorization header, a PUT or DELETE — the browser sends an OPTIONS preflight request first. If your service doesn't answer with the right Access-Control-Allow-Origin header, the real request is never sent.

For a simple GET with no custom headers, there's no preflight. The browser sends the request, your service receives it and responds, and then the browser refuses to let your JavaScript read the response. The call happened. You just can't see the result.

This matters when debugging: if your server logs show the request arriving but your client shows an error, you're looking at the second case, not a network problem.

The usual fix is to add CORS headers to your own service. Which means editing production code so a testing tool can talk to it — and those headers have a way of shipping.

The routing wall

CORS has nothing to do with this one.

A pod in a Kubernetes cluster answers to payments-service.default.svc.cluster.local. A service behind your VPN has an internal address. Neither resolves from a browser outside that network.

There's no permission to grant. The name doesn't point anywhere. Set every CORS header that exists and the request still fails.

This is why "just fix CORS" doesn't help anyone working with containers, clusters or internal services — which is most backend teams.

The usual answers, and what each costs

A browser extension. Works. You're also installing something that can read and modify traffic across the sites you visit. Plenty of security teams say no.

"Use our desktop app instead." Also works, and there's nothing wrong with a desktop app — we ship one too. The problem is when it's the only answer: a browser tool that sends you to its desktop app for something you do daily was never really a browser tool.

Change your service. Add headers, expose ports. Now your testing setup is shaping your architecture.

What AlleForge does

A local agent — a small program running on your machine. (Download the AlleForge Agent)

Hit send in the browser, and the request goes to the agent on your computer. Not to our servers. The agent makes the HTTP call and returns the response.

Two consequences:

The agent isn't a browser, so CORS doesn't apply. CORS is a browser security model. A program making an HTTP request isn't subject to it, same as curl.

The agent is already inside your network. Anything your machine can reach, it can reach. Localhost, a service on your LAN, a remote host you have access to.

For a localhost call, nothing leaves your machine.

What it doesn't do

It won't create network access that isn't there. The agent reaches what your host reaches — nothing more. A service inside a Docker container or a cluster pod isn't automatically visible to the host, so the port still needs exposing or forwarding. The agent can manage those forwards and keep them mapped to real service names, so you stop tracking which of eight localhost ports belongs to what. But if a port isn't open in your EC2 security group, nothing on your laptop reaches it, agent or not.

Something has to run on your machine — if you use the web app. The agent is a process you install and can stop. We think that beats giving up on private endpoints altogether.

If you'd rather not run it, there's a second option: AlleForge also ships as a desktop app. It's the same product with the same features, and because it already runs on your machine, it reaches local endpoints without a separate agent. Pick whichever suits you — web app plus agent, or desktop app. Same workspace either way.

It only works with AlleForge. It's built for how our web app talks to it, not as a general-purpose local proxy. Someone asked this the first time we wrote about it, and it's fair. We're considering open-sourcing it, partly for that reason.

If you want something tool-agnostic today, kubefwd handles the cluster-forwarding side well and works with anything. For plain localhost, most desktop API clients sidestep the problem by not being in a browser.

So why use a browser at all?

Because the rest of it is better there. Nothing for your teammates to install, nothing to keep updated, a link you can send someone, the same workspace from whatever machine you sit at.

The local-network problem is the one real gap in that model. It's worth solving rather than giving up everything else to avoid.


AlleForge is an API workspace for REST, GraphQL, gRPC, WebSocket, SSE, Socket.IO and SOAP — in your browser or as a desktop app. Try it free or read the docs.

See this in AlleForge

Download the AlleForge Agent