NodeJS - Express使用

2023-10-29

文章目录

  1. Express 的作用 和 Node.js内置的http模块 类似,我们可以方便、快速的创建Web网站服务器(专门对外提供Web网页资源的服务器)或API接口服务器(专门对外提供API接口的服务器)
  2. Express的本质:就是一个npm上的第三方包,其基于内置的http模块进一步封装,能够极大的提高开发效率

1. 参数

1.1 获取URL中的动态参数

通过req.params对象,可以访问到URL中,通过 : 匹配到的动态参数

app.post('/user/:id/:name', (req, res) => {
    const q = req.params;
    console.log(q);
    res.send(q);
})

POST :http://127.0.0.1:8081/user/1001/zhangsan

2. 静态资源

express提供了一个非常好用的函数,叫做express.static(),通过它,我们可以创建一个静态资源服务器。
如果要托管多个静态资源目录,需要多次调用 express.static() 函数

2.1 挂载路径前缀

如果希望在托管的静态资源访问路径之前,挂载路径前缀,则可以使用如下的方式

//express.static(),通过它,我们可以创建一个静态资源服务器
// http://127.0.0.1:8080/loess/body.html
app.use( '/loess',express.static('../../file'));

3. nodemon

nodemon 它能够监听项目文件的变动,当代码被修改后,nodemon 会自动帮我们重启项目,代替了手动频繁重启。
nodemon xxx.js

4.1路由

在Express中,路由指的是客户端的请求与服务器处理函数之间的映射关系。
Express中的路由分3部分组成,分别是请求的类型、请求的URL地址、处理函数

4.1 路由的匹配过程

每当一个请求到达服务器之后,需要先经过路由的匹配,在匹配时,会按照路由的顺序进行匹配 ( 按照定义的先后顺序、从上向下匹配),如果请求类型和请求的URL同时匹配成功,则Express会将这次请求,转交给对应的function函数进行处理。

4.2 模块化路由

为了方便对路由进行模块化的管理,Express 不建议将路由直接挂载到对象上,而是推荐将路由抽离为单独的模块。
将路由抽离为单独模块的步骤如下:
① 创建路由模块对应的js文件
② 调用express.Router0函数创建路由对象
③ 向路由对象上挂载具体的路由
④ 使用module.exports向外共享路由对象
⑤ 使用app.use0函数注册路由模块

4.3 为路由模块添加前缀
// 导入路由模块
const router = require('./webrouter')
// 注册路由模块
// app.use()函数的作用,用来注册全局中间件
app.use('/api',router);

http://127.0.0.1:8081/api/user/1001/zhangsan

5. 中间件

当一个请求到达Express的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。
在这里插入图片描述
Express的中间件,本质上是一个function处理函数,只不过中间件函数的形参列表中,必须包含next参数。而路由处理函数中只包含req和res.
next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。

5.1 全局生效的中间件

客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。
通过调用app.use(中间件函数),即可定义一个全局生效的中间件

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

const mw = function (req, res, next) {
    console.log("将mw注册为全局生效的中间件")
    next()
}
app.use(mw);
5.2 全局生效中间件的简化形式
// 定义全局中间件的简化形式
app.use((req, res, next)=>{
    console.log("将mw注册为全局生效的中间件")
    next()
})
5.3 中间件的作用

多个中间件之间,共享同一份req和res.基于这样的特性,我们可以在上游的中间件中,统一为req或res对象添加自定义的属性或方法,供下游的中间件或路由进行使用。

5.4 局部生效的中间件

不使用app.use()定义的中间件,叫做局部生效的中间件, 只在路由中生效

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

在这里插入图片描述
上例中,局部中间件只在路由"/“中生效,在路由”/user"中不生效

5.5 定义多个局部中间件
const mw1 = function (req, res, next) {
    console.log("将mw注册为第一个局部生效的中间件")
    next()
}

const mw2 = function (req, res, next) {
    console.log("将mw注册为第二个局部生效的中间件")
    next()
}

app.get('/user/:id',  mw1,mw2,function (req, res) {
    console.log(req.url);
    const q = req.query;
    res.send(q);
})
5.6 使用中间件的五个注意事项

①一定要在路田之前注册中间件
②客户端发送过来的请求,可以连续调用多个中间件进行处理
③执行完中间件的业务代码之后,不要忘记调用next()函数
④为了防止代码逻辑混乱,调用next()函数后不要再写额外的代码
⑤连续调用多个中间件时,多个中间件之间,共享req和res对象

5.7 中间件分类
5.7.1 应用级别的中间件

通过app.use() 或app.get() 或app.post(),绑定到app实例上的中间件,叫做应用级别的中间件

5.7.2 路由级别的中间件

绑定到express.Router() 实例上的中间件,叫做路由级别的中间件。它的用法和应用级别中间件没有任何区别。只不过,应用级别中间件是绑定到app实例上,路由级别中间件绑定到router实例上。

5.7.3 错误级别的中间件

错误级别中间件的作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。
格式:错误级别中间件的function处理函数中,必须有4个形参,形参顺序从前到后,分别是(err, req, res, next)。
错误级别的路由器必须放在所有路由之后

5.7.4 Express 内置的中间件

① express.static() 快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性)
② express.json() 解析JSON格式的请求体数据(有兼容性,仅在4.16.0+版本中可用)
③ express.urlencoded() 解析URL-encoded格式的请求体数据 (有兼容性,仅在4.16.0+版本中可用)
④ express.json() 和 express.urlencoded() 需要放在路由的前面,若不注册该中间件函数,路由函数中获取到的值为undefined

// 配置解析application/json格式请求数据的内置中问件
app.use(expresss.json( ))
// 配置解析application/ x-www-form-urlencoded格式请求数据的内置中间件
app.use( expresss.urlencoded({ extended: false }))

// 导入路由模块
const router = require('./webrouter')
// 注册路由模块
// app.use()函数的作用,用来注册全局中间件
app.use('/api', router);
//express.static(),通过它,我们可以创建一个静态资源服务器
app.use('/loess', expresss.static('../../file'));
5.7.5 第三方的中间件

非Express官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。

const bodyparser = require('body-parser')

app.use(bodyparser.json);
app.use(bodyparser.urlencoded({extended: false}));
5.7.6 自定义中间件
const expresss = require('express')
const app = expresss();
const qs = require('querystring')

app.use((req, res, next) => {
    // 定义一个str字符串,专门用来存储客户端发送过来的请求数据
    let str = '';
    req.on('data', (chunk) => {
        str += chunk;
    })
    req.on('end', () => {
        const body = qs.parse(str);
        req.body = body;
        next();
    })
});

app.post('/user', (req, res) => {
    console.log(req.method + "," + req.url);
    res.send(req.body);
})

6. 跨域资源共享

6.1 使用CORS跨域资源共享

CORS (Cross-Origin Resource Sharing,跨域资源共享)由一系列HTTP响应头组成,这些HTTP响应头决定浏览器是否阻止前端JS代码跨域获取资源。

浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了CORS相关的HTTP响应头,就可以解除浏览器端的跨域访问限制。

安装cors:npm i cors

const cors = require('cors')
app.use(cors) // 在路由之前注册跨域中间件
6.2 CORS的注意事项

① CORS主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了CORS的接口。
② CORS在浏览器中有兼容性。只有支持XMLHttpRequest Level2的浏览器,才能正常访问开启了CORS的服务端接口(例如: IE10+、 Chrome4+、FireFox3.5+)

6.3 CORS响应头
6.3.1 Access-Control-Allow-Origin

Access-Control-Allow-0rigin: | *
origin参数的值指定了允许访问该资源的外域URL。
通配符*,表示允许来自任何域的请求。

6.3.2 Access-Control-Allow-Headers

默认情况下,CORS仅支持客户端向服务器发送如下的9个请求头:
Accept.、Accept Language、Content-Language、 DPR、 Downlink. Save-Data、 Viewport-Width.、Width、Content- Type (值仅限于text/plain、multiprt/form-data、 application/x-www-form-urlencoded三者之一)
如果客户端向服务器发送了额外的请求头信息,则需要在服务器端,通过Access-Control-Allow-Headers对额外的请求头进行声明,否则这次请求会失败!

6.3.3 Access-Control-Allow-Methods

默认情况下,CORS仅支持客户端发起GET、POST、 HEAD请求。
如果客户端希望通过PUT、DELETE 等方式请求服务器的资源,则需要在服务器端,通过Access-Control-Alow-Methods 来指明实际请求所允许使用的HTTP方法。

6.4 CORS请求的分类
6.4.1 简单请求

同时满足以下两大条件的请求,就属于简单请求:
① 请求方式: GET、 POST、 HEAD三者之一
② HTTP头部信息不超过以下九种字段:无自定义头部字段、Accept.、Accept-Language、 Content-Language、 DPR、Downlink、Save -Data、Viewport-Width、 Width、Content- Type (只有三个值pplication/x www-form-urlencoded、multipart/form-data、 text/plain)

6.4.2 预检请求

只要符合以下任何一个条件的请求,都需要进行预检请求:
① 请求方式为 GET、POST、HEAD之外的请求Method类型
② 请求头中包含自定义头部字段
③ 向服务器发送 了application/jison 格式的数据
在浏览器与服务器正式通信之前,浏览器会先发送OPTION请求进行预检,以获知服务器是否允许该实际请求,所以这一次的OPTION请求称为"预检请求"。服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。

简单请求的特点:客户端与服务器之间只会发生一次请求。
预检请求的特点:客户端与服务器之间会发生两次请求,OPTION预检请求成功之后,才会发起真正的请求。

7. JSONP接口

浏览器端通过script标签的src属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求数据的方式叫做JSONP.
① JSONP 不属于真正的Ajax请求,因为它没有使用XMLHttpRequest这个对象。
② JSONP仅支持GET请求,不支持POST、 PUT、 DELETE等请求。

如果项目中已经配置了CORS跨域资源共享,为了防止冲突,必须在配置CORS中间件之前声明JSONP的接口。否则JSONP接口会被处理成开启了CORS的接口。示例代码如下:

7.1.1 使用JSONP接口的步骤

① 获取客户端发送过来的回调函数的名字
② 得到要通过JSONP形式发送给客户端的数据
③ 根据前两步得到的数据,拼接出一个函数调用的字符串
④ 把上一步拼接得到的字符串,响应给客户端的script标签进行解析执行

在这里插入图片描述

const cors = require('cors')
app.use(cors)

在网页中使用jQuery发起JSONP请求
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NodeJS - Express使用 的相关文章

随机推荐

  • 【蓝桥杯Python】2023.2.3-寻找2020

    题目描述 本题为填空题 只需要算出结果后 在代码中使用输出语句将所填结果输出即可 小蓝有一个数字矩阵 里面只包含数字 00 和 22 小蓝很喜欢 20202020 他想找 到这个数字矩阵中有多少个 20202020 小蓝只关注三种构成 20
  • 2023华为OD机试真题【施肥问题】

    题目描述 思路题解 首先需要计算每个果园的施肥时间 即果园面积除以施肥机能效 然后找到最小的施肥机能效 保证施肥任务能在规定时间内完成 如果施肥天数小于果园数量 则无法完成施肥任务 返回 1 如果施肥天数等于果园数量 则直接返回最大果园面积
  • 编译原理第七章笔记 -- 中间代码生成

    本文中内容整理西安交通大学软件学院吴晓军老师的ppt中 仅供学习使用 请勿转载或他用 参考教材 程序设计语言 编译原理 第3版 陈火旺等 国防工业出版社 这一章分数在35左右 两个大题 数组的引用四元式生成 控制语句当中布尔表达式的翻译 考
  • 运维必学

    欢迎关注 全栈工程师修炼指南 设为 星标 每天带你 基础入门 到 进阶实践 再到 放弃学习 专注 企业运维实践 网络安全 系统运维 应用开发 物联网实战 全栈文章 等知识分享 花开堪折直须折 莫待无花空折枝 作者 lt 安全开发运维 gt
  • VS2012编译安装VTK-5.10.1(支持Python)

    1 源码下载 到参考资料 1 下载vtk 5 10 1 zip和vtkdata 5 10 1 zip 2 源码解压 这里以D 盘为例进行说明 在D 盘中创建一个目录VTK 然后在其中创建4个目录 source build data和inst
  • mysql explain详解

    转自 http www blogjava net persister archive 2008 10 27 236813 html 在 explain的帮助下 您就知道什么时候该给表添加索引 以使用索引来查找记录从而让select 运行更快
  • Nginx反向代理与负载均衡

    文章目录 一 网关 代理与反向代理的关系 二 反向代理在系统架构中的应用场景 三 Nginx反向代理配置 1 不重定向配置 2 重定向配置 四 基于反向代理的负载均衡器 不支持https 五 负载均衡介绍 1 负载均衡策略 2 负载均衡调度
  • 三个java超级变态逻辑循环编程题

    1 有一根27厘米的细木杆 在第3厘米 7厘米 11厘米 17厘米 23厘米这五个位置上各有一只蚂蚁 木杆很细 不能同时通过一只蚂蚁 开始时 蚂蚁的头朝左还是朝右是任意的 它们只会朝前走或调头 但不会后退 当任意两只蚂蚁碰头时 两只蚂蚁会同
  • 【4】测试用例设计-判定表法

    判定表适用于有几个原因 导致几个结果的情况 实际测试中 如果输入条件较多 再加上各种输入与输出之间相互的作用关系 画出的因果图会比较复杂 容易使人混乱 为了避免这种情况 人们往往使用决策表法代替因果图法 决策表也称为 判定表 其实质就是一种
  • 各大公司薪资

    联合利华 MKT 9500 3000元安家费 普通职位 8KX12 联合利华销售代表 底薪加提成 总体一般 一般能拿到5K以上 宝洁 本8600 硕9700 博10500发14个月 11年数据 欧莱雅 MKT 6 6K X 13 11年数据
  • ajax工作原理 网页从输入url到呈现过程(TCP ,渲染引擎) 头像上传 下拉加载 节流 防抖 常见状态码

    Ajax工作原理 1 http网络传输协议 规定 前后端交互的 数据传输格式 协议 规定 前后端交互的数据传输格式 2 http协议组成两个部分 2 1前端 必须发送 请求报文格式 2 2后端 必须响应 响应报文格式 3 请求报文格式组成
  • VueX是什么?好处?何时使用?

    VueX相关 1 VueX是什么 2 使用VueX统一管理状态的好处 3 什么样的数据适合存储到Vuex中 1 VueX是什么 VueX是实现组件全局状态 数据 管理的一种机制 可以方便的实现组件之间数据的共享 如果没有VueX实现数据间的
  • 点云配准(四) Sparse Point Registration 算法浅析

    Sparse Point Registration SPR 是一篇2017年的点云配准算法 该算法的主要目的是对稀疏点云进行配准 并且取得了不错的成果和突破 本文一方面是对SPR配准算法模型进行了简单的原理解析以及附加代码实现 另一方面是对
  • c++ 的 multiple definition of `XXX‘

    文章目录 一 为什么会有多重定义问题 二 一些错误情景 1 头文件忘记加条件编译 2 类的静态变量在头文件定义 3 全局变量在 h文件定义 4 待补充 三 参考链接 一 为什么会有多重定义问题 声明 指出存储类型 并给出存储单元指定名称 定
  • C语言博客作业--嵌套循环

    一 PTA实验作业 题目1 7 1 查询水果价格 给定四种水果 分别是苹果 apple 梨 pear 桔子 orange 葡萄 grape 单价分别对应为3 00元 公斤 2 50元 公斤 4 10元 公斤 10 20元 公斤 首先在屏幕上
  • JavaScript函数的命名方式

    函数的命名方式 JavaScript代码服用单位是函数 函数可以包含一段可执行代码 也可以接受调用者传入的参数 JavaScript定义函数主要有以下三种方式 第一种方式 命名函数 第二种 匿名函数
  • 【C++】函数的设计与使用(三)重载函数、模板函数

    重载函数 参数列表不相同 可能是参数类型不相同 或者参数个数不相同 都不相同 也可以 的两个或多个函数 可以拥有相同的函数名称 编译器会把实参和每个重载函数的形参比对 找出哪个重载函数合适 所以每个重载函数的参数列表必须和其他的重载函数的不
  • ubuntu安装bochs,nasm

    1 ubuntu上安装bochs nasm 1 1 安装缘由 最近想自己做个操作系统玩一玩巩固巩固知识 工欲善其事 必先利其器 开发操作系统首先得搭建环境 编程语言上我选择C和汇编完成 开发环境是在我装的一个虚拟机ubuntu上 ubunt
  • 【满分】【华为OD机试真题2023 JAVA&JS】统计匹配的二元组个数

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 统计匹配的二元组个数 知识点数组 时间限制 1s 空间限制 32MB 限定语言 不限 题目描述 给定两个数组A和B 若数组A的某个元素A i 与数组B中的某个元素B j 满足 A
  • NodeJS - Express使用

    文章目录 1 参数 1 1 获取URL中的动态参数 2 静态资源 2 1 挂载路径前缀 3 nodemon 4 1路由 4 1 路由的匹配过程 4 2 模块化路由 4 3 为路由模块添加前缀 5 中间件 5 1 全局生效的中间件 5 2 全