Menu
CoddyTech

CORS

Part of the REST APIs section of Coddy's Node.js journey. Lesson 13 of 18.

A page on https://board.example.com calls your API with fetch, and the browser blocks the answer. Browsers let a page read answers only from its own origin, the scheme, host and port it came from, unless the server allows others with CORS headers.

OPTIONS /api/products/7
Origin: https://shop.example.com
Access-Control-Request-Method: DELETE

204 No Content
Access-Control-Allow-Origin: https://shop.example.com
Access-Control-Allow-Methods: GET, DELETE
Access-Control-Allow-Headers: Content-Type

Before a DELETE, a PATCH or a JSON body, the browser sends this preflight and goes on only if the answer allows it. Every other answer needs Access-Control-Allow-Origin too. * allows any origin, but browsers refuse it when the page sends cookies (Access-Control-Allow-Credentials: true), so name the origin. Only browsers enforce CORS: curl and the request bar ignore it.

challenge icon

Challenge

Easy
  • A middleware before the routes sets Access-Control-Allow-Origin: https://board.example.com and Access-Control-Allow-Credentials: true on every answer.
  • OPTIONS answers 204 with Access-Control-Allow-Methods listing GET, POST, PUT, PATCH, DELETE, and Access-Control-Allow-Headers: Content-Type.

Play the browser: send OPTIONS /api/tasks/2 with the header Origin: https://board.example.com, then GET /api/tasks, and read the headers of each answer.

Try it yourself

import express from 'express';
import { sendError } from './errors.js';
import taskRoutes from './routes/tasks.js';

const app = express();
app.use(express.json());

app.use('/api/tasks', taskRoutes);

// Errors from the routes end here. A body that is not valid JSON is the
// client's mistake (400); anything else is ours (500).
app.use((err, req, res, next) => {
    if (err.type === 'entity.parse.failed') {
        return sendError(res, 400, 'invalid_json', 'The body is not valid JSON');
    }
    console.error(err);
    sendError(res, 500, 'server_error', 'Something went wrong');
});

app.listen(3000, () => {
    console.log('Task tracker API on port 3000');
});
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in REST APIs