Node.js - Express框架

1. 介绍

Express 是一个基于 Node.jsWeb 应用程序框架 ,主要用于快速、简便地构建 Web 应用程序API。它是目前最流行的 Node.js Web 框架之一,具有轻量级、灵活和功能丰富的特点。

核心概念包括路由,中间件,请求与响应,以及模板引擎支持

2. Express应用的使用

通过npm进行安装express包

bash 复制代码
npm install express

示例:以下是一个最简单的Express应用程序

javascript 复制代码
const express = require('express');
const app = express();

// 路由:处理 GET 请求
app.get('/', (req, res) => {
    res.send('Hello, Express!');
});

// 路由:处理动态参数
app.get('/user/:id', (req, res) => {
    res.send(`User ID: ${req.params.id}`);
});

// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});

3. 应用程序对象

Express的核心,负责注册路由和中间件。

使用express()函数创建一个Express应用程序的实例。

javascript 复制代码
const app = express();
  1. 路由

Express提供了灵活的路由机制,用于定义应用如何响应客户端的请求

get请求

用于从服务器获取资源(例如网页、数据),请求参数通常附加在URL的查询字符串中,适用于获取数据或无敏感信息的请求

javascript 复制代码
const express = require('express');
const app = express();

app.get('/', (req, res) => {
    res.send('欢迎访问首页!');
});

// 带查询参数的 GET 请求
app.get('/search', (req, res) => {
    const query = req.query; // 获取查询参数
    res.send(`搜索内容:${query.keyword}`);
});

app.listen(3000, () => console.log('服务器运行在 http://localhost:3000'));

访问方式:直接在浏览器地址栏输入即可

javascript 复制代码
http://localhost:3000/search?keyword=express

request对象中包含了与HTTP请求相关的信息,例如请求头,URL,参数等信息

|--------------|-----------------------------------------------------------------------|
| 属性 | 描述 |
| req.params | 包含动态路由中的参数,格式为对象。例如:/user/:idreq.params.id 获取 id 参数 |
| req.query | 包含查询字符串参数,格式为对象。例如:?name=Johnreq.query.name 获取 name 参数 |
| req.body | 包含 POST 请求的请求体数据,需要中间件解析(如 express.json()express.urlencoded()) |
| req.headers | 包含 HTTP 请求头信息,格式为对象。 |
| req.headers | 包含 HTTP 请求头信息,格式为对象 |
| req.method | HTTP 请求的方法,例如:GETPOSTPUTDELETE 等 |
| req.url | 请求的完整 URL |
| req.path | 请求的路径部分(不包括查询字符串) |
| req.hostname | 请求的主机名,不包括端口号 |
| req.ip | 客户端的 IP 地址 |

示例:简易的查找返回

javascript 复制代码
const express = require("express")
const file = require("./test.json")
const app = express();

app.get('/singer/:id.html',(req,res)=>{
    let {id} = req.params;
    let result = file.find(item=>{
        if (item.id === Number(id)){return true;}
    })
    if (!result){res.statusCode=404;renderBlock.end(`<h1>404 NOT FOUND<h1>`);return;}
})

post请求

post请求则是用于向服务器提交数据,例如表单数据,JSON数据,通常会改变服务器上的数据,例如添加,修改或删除资源等操作

html 复制代码
<!DOCTYPE html>
<html>
    <head>

    </head>
    <body>
        <form method="post" action="http://127.0.0.1:3000/submit">
            <textarea placeholder="输入用户名"></textarea>
            <button>登录</button>
        </from>
    </body>
</html>
javascript 复制代码
const express = require('express');
const app = express();

app.use(express.json()); // 解析 JSON 格式的请求体
app.use(express.urlencoded({ extended: true })); // 解析 URL 编码的请求体

// POST 路由
app.post('/submit', (req, res) => {
    const body = req.body; // 获取请求体数据
    res.send(`提交的数据:${JSON.stringify(body)}`);
});

app.listen(3000, () => console.log('服务器运行在 http://localhost:3000'));

response包含了与HTTP响应相关的方法和属性,用于向客户端返回数据

|-------------------------|-----------------------------------|
| 方法 | 描述 |
| res.send(body) | 发送响应数据,可以是字符串,对象,Buffer等 |
| res.json(body) | 发送 JSON 格式的响应 |
| res.status(code) | 设置响应状态码,例如:res.status(404) |
| res.redirect(url) | 重定向到指定 URL |
| res.render(view, data) | 渲染视图模板并发送响应(需要配置模板引擎) |
| res.set(header, value) | 设置响应头 |
| res.cookie(name, value) | 设置 Cookie(需要 cookie-parser 中间件) |
| res.clearCookie(name) | 清除指定的 Cookie |
| res.type(type) | 设置content-type响应头 |
| res.sendFile() | 返回服务器中的文件 |
| res.end() | 结束响应,但不发送数据 |

Response对象常见操作:

跳转响应

javascript 复制代码
app.get('/other',(req,res)=>{res.redirect('http://www.baidu.com')})

下载响应

javascript 复制代码
app.get('/other',(req,res)=>{res.download(__dirname+'/package.json')})

JSON响应

javascript 复制代码
app.get('/other',(req,res)=>{res.json({name:"Ricardo"})})

响应文件内容

用于展示HTML文件等信息

javascript 复制代码
app.get('/other',(req,res)=>{res.sendFile(__dirname+'/test.html')})

4. express中间件

中间件(Middleware) 是 Express 中处理请求和响应的核心机制。它是一个函数,用于处理请求对象 (req)、响应对象 (res),以及在请求-响应周期中执行后续中间件的 next 方法,在路由处理之前或者之后执行。

简单来讲,中间件可以拦截请求、执行某些操作,然后决定是否将请求传递给下一个中间件;它们可以用来处理日志记录、认证、数据解析、错误处理等任务。

中间件的基本形式:

javascript 复制代码
function middleware(req, res, next) {
    // 中间件逻辑
    next(); // 调用 next() 将请求传递给下一个中间件
}

4.1 全局中间件

每一个请求到达服务器之后都会执行全局中间件函数,直接绑定到应用对象app上,作用域所有或指定的路由

javascript 复制代码
const express = require("express");
const path = require("path");
const fs = require("fs");

const app = express();

// 声明中间件函数
function recordMiddleware(req, res, next) {
    let { url, ip } = req;
    fs.appendFileSync(
        path.resolve(__dirname, './access.log'),
        `${url} ${ip}\r\n`
    );
    next(); // 必须调用 next() 将请求传递给后续中间件或路由
}

// 使用中间件
app.use(recordMiddleware);

app.get('/home', (req, res) => {
    res.send("Hello express");
});

app.get('/admin', (req, res) => {
    res.send('后台');
});

// 处理 404 请求
app.all('*', (req, res) => {
    res.send("<h1>404 NOT FOUND</h1>");
});

// 启动服务器
app.listen(3000, () => {
    console.log("The server started on port 3000");
});

4.2 专有/路由级中间件

与路由绑定,仅作用于特定路由

javascript 复制代码
function recordMiddleware(req, res, next) {
    let { url, ip } = req;
    fs.appendFileSync(
        path.resolve(__dirname, './access.log'),
        `${url} ${ip}\r\n`
    );
    next(); // 必须调用 next() 将请求传递给后续中间件或路由
}


app.get('/home', recordMiddleware,(req, res) => {
    res.send("Hello express");
});

需要在中间件中声明next才会进一步执行之后回调函数的内容

4.3 静态资源/内置中间件

javascript 复制代码
app.use(express.static(__dirname+'/public'));

根据在public文件夹下的路径即可访问对应的文件

如果public目录下有index.html文件,单独有index.html路由的话,根目录代码'/'书写谁在前显示谁

|------------------------|---------------------------------|------|
| 中间件 | 描述 | 安装 |
| express.json() | 解析 JSON 格式请求体 | 内置 |
| express.urlencoded() | 解析 URL 编码请求体(如表单数据) | 内置 |
| express.static() | 提供静态文件服务 | 内置 |
| morgan | 记录 HTTP 请求日志 | 需要安装 |
| cookie-parser | 解析请求中的 Cookie | 需要安装 |
| cors | 处理跨域请求 | 需要安装 |
| helmet | 提高应用安全性 | 需要安装 |
| body-parser | 解析请求体数据,功能与 express.json() 类似 | 需要安装 |
| express-session | 管理会话 | 需要安装 |

示例:中间件获取解析请求参数

首先,准备好我们的表单界面与服务端

html 复制代码
<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <form action="http://127.0.0.1:3000/login" method="post">
            用户名:<input type="text" name="username"><br>
            密码:<input type="password" name="password"><br>
            <button>登录</button>
        </form>
    </body>
</html>
javascript 复制代码
const express = require("express")

const app = express();

app.get('/login',(req,res)=>{
    res.sendFile(__dirname+'/form.html')
})

app.post('/login',(req,res)=>{
    res.send('获取用户的数据')
})

app.listen(3000,()=>{
    console.log('server is running...')
})
javascript 复制代码
name=John&age=25

表单所返回的数据如上述所示,我们需要在服务器端获取上述表单内容,需要使用到中间件

使用中间件解析post请求所获得的数据

javascript 复制代码
const urlencodedParser = express.urlencoded({ extended: false });

使用中间件:

javascript 复制代码
app.post('/login',urlencodedParser,(req,res)=>{
    console.log(req.body)
    res.send('获取用户的数据')
})

解析后的数据存放在req中body属性中,解析的内容以对象的形式进行保存

javascript 复制代码
{ name: 'John', age: '25' }

示例:防盗链

防止其他网站对资源进行访问,通过header请求头中refer所实现

javascript 复制代码
app.use((req,res,next)=>{
    let referer = req.get('referer');
    if (referer){
        let url = new URL(referer);
        let hostname = url.hostname; //获取站点信息
        if (hostname !== '127.0.0.1')
            {res.status(404).send('<h1>404 NOT FOUND</h1>')}
}
})

注意事项

  1. 中间件顺序很重要:中间件按照定义顺序执行。

  2. 确保调用next()如果不调用,后续中间件将不会执行。

5. 路由器(Router)

定义路由器级别的路由,用于为某一组路由逻辑进行模块化管理(即创建"迷你应用")。

它的作用范围是局部的,绑定在特定的 Router 实例上。

反之使用app.get用于处理直接挂载到整个应用程序上的 HTTP GET 请求,作用范围是全局的,绑定在整个 Express 应用实例上。

javascript 复制代码
const express = require('express');
const app = express();
const router = express.Router();

router.get('/about', (req, res) => res.send('关于页面'));
router.get('/contact', (req, res) => res.send('联系我们'));

app.use('/info', router); // 将路由器挂载到 /info 路径

app.listen(3000);

最终访问路由:

javascript 复制代码
3000/info/about

6. 路由模块化

单独创建一个文件夹用于存储不同作用的路由文件

javascript 复制代码
//   ./routes/网站首页.js
const express = require('express')

const router = express()

router.get('/home',(req,res)=>{
    res.send("网站首页")
})

module.exports = router;

模块化进行声明导出,方便在主文件中进行使用

  • 在主文件中配置路由,使用use挂载即可
javascript 复制代码
//  ./主文件.js

const express = require("express");
const router = require('./route/home.js')

const app = express();

app.use(router);

app.all("*",(req,res)=>{
    res.send("<h1>404 NOT FOUND<h1>")
})

app.listen(3000,()=>{
    console.log("This server has been started")
})
相关推荐
编程小筑16 分钟前
R语言的数据库编程
开发语言·后端·golang
大熊程序猿35 分钟前
golang 环境变量配置
开发语言·后端·golang
蒲公英的孩子1 小时前
DCU异构程序--矩阵乘
linux·c++·分布式·矩阵·架构
拾忆,想起1 小时前
深入浅出负载均衡:理解其原理并选择最适合你的实现方式
分布式·后端·微服务·负载均衡
uzong2 小时前
大模型给我的开发提效入门篇
人工智能·后端
uzong2 小时前
在mac上搭建一个安卓开发环境
后端
uzong2 小时前
新公司在使用的 Hibernate Validator 框架
java·后端
昵称难产中3 小时前
浅谈云计算11 | 虚拟机的主要功能
服务器·安全·微服务·架构·云计算
dgiij3 小时前
node.js的进程保活
后端·node.js·bash