Menu
CoddyTech

CORS

本课属于 Coddy Node.js 学习旅程的“REST API”单元。第 20 课,共 25 课。

跨源 PUT、PATCH 或 DELETE 请求,以及 Content-Type 为 JSON 的请求,通常会让浏览器先请求许可。这个 OPTIONS 请求称为预检请求。响应必须允许该来源、请求方法和请求标头。

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

在每个响应中都设置 Access-Control-Allow-Origin,包括预检请求的响应。如果只允许一个来源,你可以在每个响应中发送这个固定值:浏览器会将它与页面的来源进行比较。方法或标头的值都应是一个逗号分隔的字符串。

对于 OPTIONS,发送 204 并结束响应。对于其他方法,保留来源标头并调用 next()。将这个中间件放在最前面,在 express.json() 和路由之前,这样错误响应也会获得许可。请求栏可以检查标头,但只有浏览器会强制执行 CORS。

challenge icon

挑战

简单

此步骤会打开课程准备好的任务跟踪器 API 项目,而不是你在分页中使用的项目文件(包括 routes/tasks.js)。你之前的工作仍保留在原来的课中。编辑 server.js 前,先阅读提供的文件。这份副本包含任务的 CRUD 路由、验证、分页、筛选和排序。

在 server.js 中,添加中间件以允许来自 https://board.example.com 的请求,并将它放在 express.json() 和路由之前。将 Access-Control-Allow-Origin 设置为该确切来源,将 Access-Control-Allow-Methods 设置为 GET、POST、PUT、PATCH、DELETE、OPTIONS,并将 Access-Control-Allow-Headers 设置为 Content-Type。对于 OPTIONS,返回 204 并结束响应。对于其他方法,调用 next。

试试看:发送 OPTIONS /api/tasks/2。你应该会看到 204 和三个权限标头。发送 GET /api/tasks:它仍会返回任务列表和来源标头。向 /api/tasks 发送 POST {"title":"Order new chairs"},仍会以 201 创建任务。

亲手试试

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

// 路由中的错误最终会由这里处理。请求体不是有效的 JSON,属于
// 客户端的错误(400);其他错误则属于服务器端(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 icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

REST API中的所有课

自己练习: Express 在线编辑器