Menu
CoddyTech

JSON 响应

本课属于 Coddy Node.js 学习旅程的“Express 基础”单元。第 6 课,共 23 课。

调用你服务器的程序需要的是它能读取的数据,而不是一句话。

app.get('/api/weather', (req, res) => {
    res.json({ city: 'Oslo', temp: 4, rain: true });
});

JSON 是一种用于表示对象和数组的文本格式。res.json(value) 会将值转换为 JSON,并将 Content-Type 标头设置为 application/json;标头是随响应发送的一行带名称的内容,这个标头说明后面是什么类型的主体。客户端会收到 {"city":"Oslo","temp":4,"rain":true},并将 temp 读取为数字。

使用字符串调用 res.send 会发送 text/html,程序需要自行解析它。面向程序的路由通常以 /api 开头,这样页面和数据就不会共用同一路径。

challenge icon

挑战

简单

像手机应用这样的程序,需要以可读取的形式获取 Recipe Box 的数据。在页面旁边添加一个 JSON API。

  1. 在 server.js 中添加一个 /api/recipes 路由。它会将整个 recipes 数组作为 JSON 发送。
  2. 添加一个 /api/recipes/:id 路由。它像 /recipes/:id 那样查找食谱,并将整个食谱对象作为 JSON 发送,而不只是发送标题。对于食谱 2,也就是包含 "id": 2、"title": "Pancakes"、"tags": ["breakfast", "sweet"] 以及份数的对象。
  3. 如果没有食谱的 id 与该 id 匹配,就返回状态码 404。你可以像页面那样发送文本 No such recipe。

试试看:点击“运行”,然后发送 /api/recipes。你应该会看到 4 道食谱组成的列表,第一道是 Tomato Soup。发送 /api/recipes/2:会得到 Pancakes 对象。发送 /api/recipes/99:会得到状态码 404。在 Headers 标签页中,/api/recipes 的 Content-Type 是 application/json。然后发送 /about:它的 Content-Type 是 text/html,因为 res.send 发送字符串时会返回一个页面。

亲手试试

import express from 'express';
import { recipes } from './data.js';

const app = express();

app.get('/', (req, res) => {
    res.send('Welcome to Recipe Box');
});

// type('text') 会发送纯文本,所以每个标题都会单独显示在一行。
app.get('/recipes', (req, res) => {
    const { tag } = req.query;
    const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
    res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});

app.get('/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).send('No such recipe');
        return;
    }
    res.send(recipe.title);
});

app.get('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});
quiz icon自我测试

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

Express 基础中的所有课

自己练习: Express 在线编辑器