Menu
CoddyTech

CORS

Thuộc phần REST API trong hành trình Node.js của Coddy. Bài học 20 trên 25.

Một yêu cầu PUT, PATCH hoặc DELETE khác nguồn, hoặc một yêu cầu có Content-Type là JSON, thường khiến trình duyệt yêu cầu cấp quyền trước. Yêu cầu OPTIONS này là một yêu cầu preflight. Phản hồi phải cho phép nguồn gốc, phương thức và các tiêu đề yêu cầu.

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://shop.example.com
Access-Control-Allow-Methods: GET, POST, PATCH, OPTIONS
Access-Control-Allow-Headers: Content-Type

Đặt Access-Control-Allow-Origin trong mọi phản hồi, kể cả phản hồi preflight. Khi chỉ cho phép một nguồn gốc, bạn có thể gửi giá trị cố định đó trong mọi phản hồi: trình duyệt sẽ so sánh giá trị này với nguồn gốc của trang. Mỗi giá trị phương thức hoặc tiêu đề là một chuỗi gồm các mục được phân tách bằng dấu phẩy.

Với OPTIONS, hãy gửi mã 204 rồi kết thúc phản hồi. Với các phương thức khác, hãy giữ lại tiêu đề nguồn gốc và gọi next(). Đặt middleware này lên đầu, trước express.json() và các route, để cả phản hồi lỗi cũng có quyền. Thanh yêu cầu có thể kiểm tra các tiêu đề, nhưng chỉ trình duyệt mới thực thi CORS.

challenge icon

Thử thách

Dễ

Bước này mở dự án API theo dõi công việc đã chuẩn bị sẵn của khóa học, thay vì các tệp dự án từ Phân trang (bao gồm routes/tasks.js). Phần bạn đã làm trước đó vẫn nằm trong bài học riêng. Đọc các tệp được cung cấp trước khi chỉnh sửa server.js. Bản sao này có các tuyến CRUD công việc, xác thực, phân trang, bộ lọc và sắp xếp.

Trong server.js, trước express.json() và các tuyến, thêm middleware cho phép https://board.example.com. Đặt Access-Control-Allow-Origin thành đúng origin đó, Access-Control-Allow-Methods thành GET, POST, PUT, PATCH, DELETE, OPTIONS, và Access-Control-Allow-Headers thành Content-Type. Với OPTIONS, phản hồi bằng mã 204 rồi kết thúc. Với các phương thức khác, gọi next.

Thử: gửi OPTIONS /api/tasks/2. Bạn sẽ thấy mã 204 và ba header quyền truy cập. Gửi GET /api/tasks: API vẫn trả về danh sách công việc và header origin. POST {"title":"Order new chairs"} đến /api/tasks vẫn tạo công việc với mã 201.

Tự làm thử

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);

// Lỗi từ các route được xử lý tại đây. Nếu phần thân yêu cầu không phải JSON hợp lệ thì đó là
// lỗi của client (400); các lỗi khác là lỗi phía chúng ta (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 iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong REST API

Tự luyện tập: Playground Express