Node.js - Express框架

1. 介绍

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

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

2. Express应用的使用

通过npm进行安装express包

npm install express

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

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应用程序的实例。

const app = express();

4. 路由

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

get请求

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

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

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

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.methodHTTP 请求的方法,例如:GETPOSTPUTDELETE
req.url请求的完整 URL
req.path请求的路径部分(不包括查询字符串)
req.hostname请求的主机名,不包括端口号
req.ip客户端的 IP 地址

示例:简易的查找返回

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数据,通常会改变服务器上的数据,例如添加,修改或删除资源等操作

<!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>
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对象常见操作:

跳转响应

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

下载响应

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

JSON响应

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

响应文件内容

用于展示HTML文件等信息

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

4. express中间件

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

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

中间件的基本形式:

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

4.1 全局中间件

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

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 专有/路由级中间件

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

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 静态资源/内置中间件

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管理会话需要安装

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

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

<!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>
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...')
})

name=John&age=25

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

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

const urlencodedParser = express.urlencoded({ extended: false });

使用中间件:

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

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

{ name: 'John', age: '25' }

示例:防盗链

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

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 应用实例上。

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

最终访问路由:

3000/info/about

6. 路由模块化

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

//   ./routes/网站首页.js
const express = require('express')

const router = express()

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

module.exports = router;

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

- 在主文件中配置路由,使用use挂载即可

//  ./主文件.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")
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/954080.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

day08_Kafka

文章目录 day08_Kafka课程笔记一、今日课程内容一、消息队列&#xff08;了解&#xff09;**为什么消息队列就像是“数据的快递员”&#xff1f;****实际意义**1、产生背景2、消息队列介绍2.1 常见的消息队列产品2.2 应用场景2.3 消息队列中两种消息模型 二、Kafka的基本介绍1、…

459. 重复的子字符串【力扣】——kmp拼接字符串解法

常规kmp解答 class Solution { public:void getNext(int *next,string s){int j0;next[0]0;for(int i1;i<s.size();i){while(j>0 && s[i]!s[j]){jnext[j-1];}if(s[i]s[j]) j;next[i]j;}}bool repeatedSubstringPattern(string s) {if(s.size()0) return false;i…

浅谈云计算06 | 云管理系统架构

云管理系统架构 一、云管理系统架构&#xff08;一&#xff09;远程管理系统&#xff08;二&#xff09;资源管理系统&#xff08;三&#xff09;SLA 管理系统&#xff08;四&#xff09;计费管理系统 二、安全与可靠性保障&#xff08;一&#xff09;数据安全防线&#xff08;…

【STM32】HAL库USB实现软件升级DFU的功能操作及配置

【STM32】HAL库USB实现软件升级DFU的功能操作及配置 文章目录 DFUHAL库的DFU配置修改代码添加条件判断和跳转代码段DFU烧录附录&#xff1a;Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时 位带操作位带代码位带宏…

PHP答题考试系统

&#x1f50d; 这是一款由PHP与Uniapp强强联手打造的小程序答题考试系统&#xff0c;它如同智慧教育领域中的一颗璀璨明珠&#xff0c;凭借其强大的功能和灵活多变的应用&#xff0c;牢牢吸引了无数求知者的目光。系统全面覆盖了多种试题类型&#xff0c;从基础易懂的判断题、单…

瑞芯微 RK 系列 RK3588 使用 ffmpeg-rockchip 实现 MPP 视频硬件编解码-代码版

前言 在上一篇文章中&#xff0c;我们讲解了如何使用 ffmpeg-rockchip 通过命令来实现 MPP 视频硬件编解码和 RGA 硬件图形加速&#xff0c;在这篇文章&#xff0c;我将讲解如何使用 ffmpeg-rockchip 用户空间库&#xff08;代码&#xff09;实现 MPP 硬件编解码。 本文不仅适…

Element Plus 之 el-table相同行合并(通用函数),相同列合并(自行判断需合并的字段以及相应的列下标)

展示 代码 <el-table :data"tableData" border style"width: 100%" :span-method"objectSpanMethod"><el-table-column prop"date" label"Date" width"180" align"center" /><el-table…

深入理解计算机系统阅读笔记-第十二章

第12章 网络编程 12.1 客户端-服务器编程模型 每个网络应用都是基于客户端-服务器模型的。根据这个模型&#xff0c;一个应用时由一个服务器进程和一个或者多个客户端进程组成。服务器管理某种资源&#xff0c;并且通过操作这种资源来为它的客户端提供某种服务。例如&#xf…

ubuntu20.04安装MySQL5.7

deb安装 下载deb文件并配置 wget https://repo.mysql.com//mysql-apt-config_0.8.12-1_all.deb sudo dpkg -i mysql-apt-config_0.8.12-1_all.deb我使用xshell可以正常。 这个弹出框里&#xff0c;选择的是“ubuntu bionic”。(在终端工具上&#xff0c;有可能显示不了选项)【…

CSS | CSS实现两栏布局(左边定宽 右边自适应,左右成比自适应)

目录 一、左边定宽 右边自适应 1.浮动 2.利用浮动margin 3.定位margin 4.flex布局 5.table 布局 二、左右成比自适应 1:1 1flex布局 table布局 1:2 flex布局 三列布局链接&#xff1a;CSS | 实现三列布局&#xff08;两边边定宽 中间自适应&#xff0c;自适应成比&#xff09;-…

Win10微调大语言模型ChatGLM2-6B

在《Win10本地部署大语言模型ChatGLM2-6B-CSDN博客》基础上进行&#xff0c;官方文档在这里&#xff0c;参考了这篇文章 首先确保ChatGLM2-6B下的有ptuning AdvertiseGen下载地址1&#xff0c;地址2&#xff0c;文件中数据留几行 模型文件下载地址 &#xff08;注意&#xff1…

Java中异常的学习

目录 Java 异常概述 异常的抛出机制 异常的解决方法(处理机制) Java异常体系结构 常见的异常 异常处理 try catch finally throws throw 运行期异常和编译期异常 自定义异常 Java 异常概述 在使用计算机语言进行项目开发的过程中&#xff0c;即使程序员把代码写得尽…

python 连接高斯数据库报错

问题1&#xff1a;报错信息&#xff1a; import psycopg2时报错 /lib64/libgssapi_krib5.so.2 symbol krb5_ser_contect_init version krb5_3_MIT not defined in file libkrb5.so.3 错误原因&#xff1a; 解决&#xff1a; 若通过更换krb相关安装包&#xff0c;psycopg2 …

excel 整理表格,分割一列变成多列数据

数据准备 对于很多系统页面的数据是没有办法下载的。 这里用表格数据来举例。随便做数据的准备。想要看excel部分的可以把这里跳过&#xff0c;从数据准备完成开始看。 需要一点前端基础知识&#xff0c;但不多&#xff08;不会也行&#xff09;。 把鼠标放在你想要拿到本地的…

刀客doc:快手的商业化架构为什么又调了?

一、 1月10日&#xff0c;快手商业化及电商事业部进行新一轮的架构调整。作为2025年快手的第一次大调整&#xff0c;变动最大的是负责广告业务的商业化事业部。快手商业化将原来的8个业务中心&#xff0c;现在统合成了5个&#xff0c;行业归拢看上去更加明晰了。 根据自媒体《…

thinkphp 5.0 结合redis 做延迟队列,队列无法被消费

目录 一、Linux 环境下 二、如何验证消息队列被正确监听 一、Linux 环境下 项目部署在Linux 环境下&#xff0c;首先找到项目的部署路径&#xff0c;接着输入命令,这个命令是以守护进程方式进行监听你的队列&#xff0c;只要redis 不关闭 就可以一直监听这个队列 nohup php …

计算机网络 (40)域名系统DNS

前言 计算机网络域名系统DNS&#xff08;Domain Name System&#xff09;是互联网的基础技术之一&#xff0c;它负责将人类可读的域名转换为计算机用来通信的数字IP地址。 一、基本概念 DNS的主要目的是将域名解析或翻译为IP地址&#xff0c;使得用户可以通过简单易记的域名来访…

做一个 简单的Django 《股票自选助手》显示 用akshare 库(A股数据获取)

图&#xff1a; 股票自选助手 这是一个基于 Django 开发的 A 股自选股票信息查看系统。系统使用 akshare 库获取实时股票数据&#xff0c;支持添加、删除和更新股票信息。 功能特点 支持添加自选股票实时显示股票价格和涨跌幅一键更新所有股票数据支持删除不需要的股票使用中…

C#使用OpenTK绘制3D可拖动旋转图形三棱锥

接上篇,绘制着色矩形 C#使用OpenTK绘制一个着色矩形-CSDN博客 上一篇安装OpenTK.GLControl后,这里可以直接拖动控件GLControl 我们会发现GLControl继承于UserControl //// 摘要:// OpenGL-aware WinForms control. The WinForms designer will always call the default//…

《C++11》nullptr介绍:从NULL说起

在C11之前&#xff0c;我们通常使用NULL来表示空指针。然而&#xff0c;NULL在C中有一些问题和限制&#xff0c;这就是C11引入nullptr的原因。本文将详细介绍nullptr的定义、用法和优点。 1. NULL的问题 在C中&#xff0c;NULL实际上是一个整数0&#xff0c;而不是一个真正的…