Skip to content

介绍与使用

  1. 安装

    sh
    npm i express
  2. 在项目根目录创建入口文件:app.js

    js
    // 引入 express
    const express = require('express');
    
    // 创建对象
    const app = express();
    
    // 创建路由
    app.get('/home', (req, res) => {
        res.send('Helllo')
    });
    
    // 监听端口,启动服务
    app.listen(3000, () => {
        console.log('服务器请求成功: http://localhost:3000');
    })
  3. 启动项目

    sh
    node app.js
    nodemon app.js

路由

定义

路由确定了应用程序如何响应客户端对特定端点的请求。

组成

一个路由的组成包括 请求方法请求路径回调函数 组成。

使用

在 express 中提供了一系列方法,可以很方便的使用路由,使用格式:

js
app.<method>(path, callback);

请求方法

  1. 常用的请求方法有 getpostdeletepull

  2. 每个方法对应一个 API

    js
    app.get('/home', (req, res) => {});			// 接收 Get 请求
    app.post('/home', (req, res) => {});		// 接收 POST 请求
    app.delete('/home', (req, res) => {});		// 接收 delete 请求
    app.pull('/home', (req, res) => {});		// 接收 pull 请求
    app.all('/home', (req, res) => {});			// 接收所有类型的请求
    app.all('*', (req, res) => {});				// 404 响应

获取请求参数

获取头部参数

js
app.get('/home', (req, res) => {
    console.log(req.path);  // 请求路径
    console.log(req.query); // query 参数
    console.log(req.ip);    // 客户端 ip 地址
    res.send('Hello')
})

获取路由参数

js
app.get('/:id', (req, res) => {
    console.log(req.params.id);	// 路由里的参数
    res.send('Hello')
})

设置响应

基本设置

js
app.get('/home', (req, res) => {
    res.status(200);            // 状态码
    res.set('token', 'HSAK');   // 响应头
    res.send('我是响应体');      // 响应体
})

其他设置

  1. 重定向

    js
    res.redirect('https://www.baidu.com');
  2. 下载文件

    js
    res.download(__dirname + '/package.json');
  3. JSON 响应

    js
    res.json({ name: 'iGma', age: 20 });
  4. 响应文件(PDF、图片等)

    js
    res.sendFile(__dirname + '/package.json')

中间件

什么是中间件?

中间件本质是一个回调函数,中间件函数可以像路由回调一样访问请求对象、响应对象。

作用

使用函数封装公共的操作,简化代码。比如 token 认证等。

类型

  1. 全局中间件
  2. 路由中间件

全局中间件

  1. 每个请求到达服务器之后都会执行全局中间件函数。

  2. 写法与 Vue 中的全局前置路由守卫很像。

  3. 案例:记录每一次请求的 IP 地址和请求路径,写入根目录的 log.txt 文件中

    js
    const express = require('express');
    const fs = require('fs');
    const app = express();
    
    // 全局中间件
    app.use((req, res, next) => {
        let { ip, path } = req;
        fs.appendFileSync(`${__dirname}/log.txt`, `path: ${path} ------ ip: ${ip} \r\n`);
        next();
    })
    
    app.get('/home', (req, res) => {
        res.send('Home API');
    })
    
    app.get('/about', (req, res) => {
        res.send('About API');
    })
    
    app.all('*', (req, res) => {
        res.send('404 服务异常');
    })
    
    app.listen(3000, () => {
        console.log('服务器请求成功: http://localhost:3000');
    })
  4. 注意: 全局中间件函数必须写到所有路由的上面,否则没效果。

路由中间件

  1. 只对特定路由有效。

  2. /home 接口进行权限校验

    js
    const express = require('express');
    const app = express();
    
    // 定义中间件
    const rule = (req, res, next) => {
        if (req.query.code === '200') next();
        else res.send('无权访问');
    }
    
    app.get('/home', rule, (req, res) => {
        res.send('Home API');
    })
    
    app.get('/about', (req, res) => {
        res.send('About API');
    })
    
    app.all('*', (req, res) => {
        res.send('404 服务异常');
    })
    
    app.listen(3000, () => {
        console.log('服务器请求成功: http://localhost:3000');
    })

静态资源中间件

通过 express.static 函数指定静态资源目录。

js
app.use(express.static(`${__dirname}/access`))

获取请求体数据

  1. 安装 body-parser

    sh
    npm i body-parser
  2. 全局应用

    js
    const express = require('express');
    const app = express();
    const bp = require('body-parser');
    
    app.use(bp.urlencoded({ extended: true }));     // application/x-www-form-urlencoded
    // app.use(bp.json());                     			// application/json
    
    app.post('/home', (req, res) => {
        console.log(req.body);
        res.send('请求成功')
    })
    
    app.listen(3000, () => {
        console.log('服务器请求成功: http://localhost:3000');
    })
  3. 路由应用

    js
    const express = require('express');
    const app = express();
    const bp = require('body-parser');
    
    const qs = bp.urlencoded({ extended: true });   // application/x-www-form-urlencoded
    const js = bp.json();                           // application/json
    
    app.post('/home', qs, (req, res) => {
        console.log(req.body);
        res.send('请求成功')
    })
    
    app.listen(3000, () => {
        console.log('服务器请求成功: http://localhost:3000');
    })

防盗链

定义

防止外部网站盗用自己网站的资源

代码实现

js
const express = require('express');
const app = express();

app.use((req, res, next) => {
    // 通过请求头中的 referer 实现防盗链
    let referer = req.get('referer');
    if (referer) {
        // 获取请求域名
        let hostname = new URL(referer).hostname;
        if (hostname !== '127.0.0.1') {
            res.status(400).send('404 服务异常');
            return;
        }
    }
    next();
})

app.get('/home', (req, res) => {
    res.send('请求成功')
})

app.listen(3000, () => {
    console.log('服务器请求成功: http://localhost:3000');
})

路由模块化

我们在前面的代码中把所有路由写到了入口文件 app.js 中,这样阅读起来很不方便,可以在根目录中创建路由文件夹,把针对不同数据表的路由抽离出来。例:抽离用户表对应的所有路由到 /router/user.js

/router/user.js

js
const router = require('express').Router();

router.get('/user/login', (req, res) => {
    res.send('请求成功!');
})

module.exports = router;

app.js

js
const express = require('express');
const app = express();

app.use(require('./router/user'));

app.listen(3000, () => {
    console.log('服务器请求成功: http://localhost:3000');
})

基于 MIT 许可发布