NodeJS - Express使用

news2024/11/16 5:40:55

文章目录

    • 1. 参数
        • 1.1 获取URL中的动态参数
    • 2. 静态资源
        • 2.1 挂载路径前缀
    • 3. nodemon
    • 4.1路由
        • 4.1 路由的匹配过程
        • 4.2 模块化路由
        • 4.3 为路由模块添加前缀
    • 5. 中间件
        • 5.1 全局生效的中间件
        • 5.2 全局生效中间件的简化形式
        • 5.3 中间件的作用
        • 5.4 局部生效的中间件
        • 5.5 定义多个局部中间件
        • 5.6 使用中间件的五个注意事项
        • 5.7 中间件分类
            • 5.7.1 应用级别的中间件
            • 5.7.2 路由级别的中间件
            • 5.7.3 错误级别的中间件
            • 5.7.4 Express 内置的中间件
            • 5.7.5 第三方的中间件
            • 5.7.6 自定义中间件
    • 6. 跨域资源共享
        • 6.1 使用CORS跨域资源共享
        • 6.2 CORS的注意事项
        • 6.3 CORS响应头
            • 6.3.1 Access-Control-Allow-Origin
            • 6.3.2 Access-Control-Allow-Headers
            • 6.3.3 Access-Control-Allow-Methods
        • 6.4 CORS请求的分类
            • 6.4.1 简单请求
            • 6.4.2 预检请求
    • 7. JSONP接口
        • 7.1.1 使用JSONP接口的步骤

  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请求
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机xxxxxxx

文章目录1.互联网的两大组成部分(边缘部分与核心部分)的特点是什么?它们的工作方式各有什么特点?2.简述分组交换的要点。3.试从多个方面比较电路交换、报文交换和分组交换的主要优缺点。4.网络协议的三个要素是什么?各…

十二、生产者和消费者问题、队列、线程池

内容 理解消费者、生产者的案例执行过程, 理解用队列方式做消费者、生产者的案例 会使用线程池运行任务, 理解ThreadPoolExecutor7个参数的含义(会根据需要 通过参数控制线程池的总数量) 匿名内部类里的异常处理 Thread 使用匿名内部类…

VScode中不同目录间python库函数的调用

问题描述 vscode中跨目录的模块调用远不如pycharm中的来的简单,在pycharm中即使是不同库文件夹中子函数也可以进行互相调用。而在VScode中则需要我们手动向其中添加依赖路径。如下相同的文件结构,在pycharm中可以简单的在model_arc_pesudo中导入model中的…

HTTP传输过程

简介 HTTPS是在HTTP的基础上和ssl/tls证书结合起来的一种协议,保证了传输过程中的安全性,减少了被恶意劫持的可能.很好的解决了解决了http的三个缺点(被监听、被篡改、被伪装) 对称加密和非对称加密 对称加密 即加密的密钥和解密的密钥相同, 非对称加…

1801. 积压订单中的订单总数

插: 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 坚持不懈,越努力越幸运,大家一起学习鸭~~~ 题目: 给你一个二维整数数组 orders &…

【HTMLCSS】运维、后端你该会的前端基本内容

文章目录前言一、HTML5基础1.1、前端开发的核心技术1.2、Web组成标准1.3、HTML 实例1.3.1、第一个网页1.4、 文本标签1.5、转义字符1.6、图片1.7、超链接1.8、列表1.8.1、无序列表1.8.2、有序列表1.8.3、自定义列表1.9、表格1.9.1、合并单元格1.10、表单二、CSS基础2.1、入门2.…

【论文导读】Stable Learning via Sparse Variable Independence

准备follow一下稳定学习的系列论文,从这篇开始吧。 AAAI2023上的,主要是根据前几年稳定学习组提出的SV特征分类、关注稳定的S特征的样本重加权的优化 针对问题和措施: 稳定学习算法采用的样本重加权有弊端: 1,在有限…

ESP8266 SDK开发之AiThinkerIDE_V1.5.2安装、配置以及编写一个程序

【本文发布于https://blog.csdn.net/Stack_/article/details/128509864,未经允许不得转载,转载须注明出处】 前言 乐鑫官方不搞IDE,安信可搞了IDE,但是各版本之间安装配置有差异,还没有文档说明。官方安装配置教程不完…

IEEE论文投稿流程

转载文章 这是篇节省你翻论坛、查资料的文章。 我将把每一步尽量写的清楚,能够让新手按照这篇文章进行完整的投稿。 即使你从未投过稿,完全不了解IEEE的投稿流程,希望按照这篇文章,能够帮助你流畅无误的投稿 这是针对本科生和低年…

springboot整合springcloud之nacos配置中心

整合配置中心nacos 应用场景&#xff0c;每次改配置要重新启动才能生效&#xff0c;而把配置放到nacos上&#xff0c;如有修改&#xff0c;那么发布后项目自动就生效了。 场景2&#xff1a;不同微服务单独设置一个命名空间。 一、项目操作 1.引入依赖 <!--使用spring-cloud…

JDBC---Maven之jdbc连接数据库

Maven之jdbc连接数据库 这里需提前将maven环境配置好 链接: Maven环境配置 文章目录Maven之jdbc连接数据库JDBC创建Maven工程JDBC访问数据库步骤1.Class.forName()加载驱动2.DriverManager获取Connection连接3.创建Statement执行SQL语句4.返回ResultSet查询结果()5.释放资源JD…

vsmoon靶场实战笔记

vsmoon靶场实战笔记 web打点 信息收集 nmap扫描端口 扫描结果 └─$ nmap -sV -A 192.168.1.106 -Pn Starting Nmap 7.92 ( https://nmap.org ) at 2023-01-01 12:51 CST Nmap scan report for 192.168.1.106 Host is up (0.00014s latency). Not shown: 986 closed tcp p…

YOLOv5更换骨干网络之 GhostNet

论文地址&#xff1a;https://arxiv.org/abs/1911.11907 代码地址&#xff1a;https://github.com/huawei-noah/ghostnet 由于内存和计算资源有限&#xff0c;在嵌入式设备上部署卷积神经网络&#xff08;CNN&#xff09;很困难。特征图中的冗余是那些成功的神经网络的重要特征…

年度征文 | 回顾2022,展望2023(我难忘的2022,我憧憬的2023)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

用javascript分类刷leetcode7.双指针(图文视频讲解)

双指针 普通指针&#xff1a;两指针同一方向或不同方向对撞指针&#xff1a;两指针互相靠拢快慢指针&#xff1a;一快一慢 141. 环形链表 (easy) 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再…

LeetCode字符串经典题目(四)

1. LeetCode344. 反转字符串 2. LeetCode541. 反转字符串 II 3. LeetCode剑指 Offer 05. 替换空格 4. LeetCode151. 反转字符串中的单词 5. LeetCode剑指 Offer 58 - II. 左旋转字符串 6. LeetCode28. 找出字符串中第一个匹配项的下标​ 7. LeetCode459. 重复的子字符串​…

Mac内存空间不足如何释放储存空间?深度清理Mac磁盘空间的方法教程

今日coco玛奇朵将分享一些能够释放大量Mac内存空间的方法&#xff0c;以便大家能够优化Mac的运行速度外还能规避由于Mac空间不足而导致安装Ventura时出现的一系列问题。 大家都知道更新Macos都需要预备非常大的内存空间才能进行&#xff0c;当更新完Macos之后都会留下大量的备…

台大应用深度学习笔记

deep learning end-to-end training 1. 神经元 1.1 为什么需要bias&#xff1f; 为了给对应位置一个prior&#xff0c;给它一个初始值&#xff0c;b越大&#xff0c;σ(z)11e−z\sigma(z) \frac{1}{1e^{-z}}σ(z)1e−z1​越大&#xff0c;越趋向于1. 多层神经网络&#xff…

安装Windows和Ubuntu双系统

制作Ubuntu安装盘在Windows上查看磁盘格式 不同的磁盘格式&#xff0c;需要跟BIOS里面不同的引导模式配合来启动操作系统&#xff0c;如下图&#xff1a; 我的电脑是GPT格式&#xff1a; 准备好给Ubuntu的磁盘空间 在Windows系统中&#xff0c;在一个200G的清空数据的磁盘上…

【Flask-Web】基于layui前端模板搭建简易管理系统

1. JavaScript 1.1. 函数 var cars ["Saab", "Volvo", "BMW"]; var txt "string"; var b2new Boolean(1); var x Math.PI; // 返回PI var y Math.sqrt(16); // 返回16的平方根 var num new Number(value); try {adddlert("…