Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

CORS

The browser does not let JavaScript on one site's page read responses from a server at another address unless the server explicitly allows it. The permission mechanism is called CORS (Cross-Origin Resource Sharing). If the blog's frontend runs on http://localhost:5173 and the API on http://localhost:3000, the browser blocks the requests without CORS.

What the problem looks like

Open the frontend page and run a request to the API in the browser console:

// browser console on http://localhost:5173
const response = await fetch('http://localhost:3000/posts');
console.log(await response.json());

The console shows an error with the words "blocked by CORS policy". The server did receive the request and answer — it is the browser that blocks it. curl and other servers do not check CORS.

Installing

npm install @fastify/cors

Registering

Allow requests from the frontend address in src/app.js:

// src/app.js
import cors from '@fastify/cors';
 
app.register(cors, {
  origin: 'http://localhost:5173',
});

Repeat the request in the console — now the list of posts is printed. The plugin adds the Access-Control-Allow-Origin header to replies, which tells the browser that reading is allowed.

Methods and headers

Before PUT, DELETE and requests with an Authorization header, the browser first sends an OPTIONS preflight request. The plugin answers it, but it is better to list the allowed methods explicitly:

// src/app.js
app.register(cors, {
  origin: ['http://localhost:5173', 'https://blog.example.com'],
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
});

Now the frontend, both on the local address and on the production domain, can create and delete posts with a token.

Main options

OptionWhat it sets
originAllowed addresses: a string, an array or true for any
methodsAllowed HTTP methods
allowedHeadersHeaders the client may send
credentialsAllow sending cookies
maxAgeHow many seconds the browser remembers the OPTIONS answer

It is convenient to keep the addresses in .env so the real domain can be set on the server.

Common mistake

origin: true or '*' lets any site read the API. That is fine for a public API, but if the API works with tokens or cookies, list only your own addresses — otherwise a foreign page can send requests on behalf of your users.

Thanks for reading!

Donate to the site — we work hard for you.