Explain Codes LogoExplain Codes Logo

Why does my http://localhost CORS origin not work?

javascript
cors
http-requests
web-development
Nikita BarsukovbyNikita Barsukov·Sep 19, 2024
TLDR

To quickly solve CORS issues with localhost, add a response header Access-Control-Allow-Origin: * to allow any origin, or "http://localhost:PORT" to allow a specific origin. Here's an Express.js, Node.js snippet:

app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', 'http://localhost:PORT'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); res.setHeader('Access-Control-Allow-Credentials', true); // Remember kids, wildcards are like double-edged swords; they can get you as well. next(); });

Replace PORT with your client’s actual port. For production, restrict the origin to secure your application.

Overcoming Chrome and its restrictions

Chrome poses some challenges with CORS when using localhost. One workaround is substituting the domain localhost with localho.st, which points to IP 127.0.0.1.

http://localho.st:PORT

For testing in Chrome, you could disable web security temporarily.

chrome.exe --disable-web-security --user-data-dir="[some directory here]"

Mind you, this is the equivalent of walking into a zombie apocalypse with a vaseline shield.

Developer-friendly Chrome extension

Use a Chrome extension for testing, such as "Allow-Control-Allow-Origin: *", which adds CORS headers as needed.

Warning: Remember that this is a temporary measure and can be a certain recipe for disaster when used in production.

Server setup: Getting it right

If your server response lacks the correct Access-Control-Allow-Origin header, http://localhost won't be permitted:

Access-Control-Allow-Origin: http://localhost:PORT

You can extend the Chrome CORS Extension for more granular control using source code available on GitHub.

Client-side Capers

CORS errors could also be a result of the client script. For instance, when using XMLHttpRequest, you might encounter CORS restrictions:

var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://localhost:PORT/data', true); // Thou shall verify thy protocol and port (and server settings too).

Embrace the power of proxy

local-cors-proxy offers a simplified solution to bypass CORS restrictions. Install it via npm and create a proxy server:

npm install -g local-cors-proxy

Update your client script to point at the proxy:

var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://localho.st:PORT/proxy', true); // I'm the proxy master, and I choose to bypass CORS restrictions.

Handling Preflight Lift-off

For certain requests, browsers perform a preflight request using the OPTIONS method. Here's how you can handle it:

app.options('*', (req, res) => { res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS,PUT,PATCH,DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization'); res.send(200); // Now you're ready for takeoff! });

Dynamic Origins and validation

In scenarios where CORS origins can't be hardcoded, validate the HTTP_ORIGIN against a list of allowed domains:

const allowedOrigins = ['http://localhost:3000', 'https://yourapp.com']; const origin = req.headers.origin; if (allowedOrigins.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin); // You're on the list! Welcome to the party! }

PHP: Handling Preflight the Right way

header('Access-Control-Allow-Origin: *'); // Other headers... http_response_code(204); // No Content exit(0); // Take it easy, the mission is over!

Always end your preflight handling script in PHP with exit(0)