Node.js:Express 服务 路由

Node.js:Express 服务 & 路由

    • 创建服务
    • 处理请求
      • req对象
    • 静态资源托管
      • 托管多个资源
      • 挂载路径前缀
    • 路由
      • 模块化


ExpressNode.js上的一个第三方框架,可以快速开发一个web框架。本质是一个包,可以通过npm直接下载。

创建服务

Express创建一个服务器的流程非常简单:

  1. 导入Express
  2. 实例化Express为一个服务
  3. 监听端口,开始服务

如下:

const express = require('express')
const app = express()app.listen(80, () => {console.log("创建web服务成功")
})

处理请求

Express被实例化为app服务后,就可以通过这个服务来进行请求处理:

app.get('url', (req, res) => {// ...
})app.post('url', (req, res) => {// ...
})

以上两个方法,分别处理getpost请求,触发回调函数,req是请求信息,res是响应信息,这和http模块类似。

如果在处理请求时,需要向客户端发送消息,调用res.send方法:

app.get('/login', (req, res) => {res.send("hello Express")
})

运行服务后,访问127.0.0.1就可以得到响应结结果:

在这里插入图片描述

req对象

在使用get请求时,常会通过?携带一些参数信息,这些参数可以通过req.query获取到。

app.get('/login', (req, res) => {res.send(req.query)
})

启动服务后,用户携带的参数存储在req.query中,直接将这个对象发回给浏览器:

在这里插入图片描述

访问服务器时,携带了数据?name=zhangsan&age=20,最后被服务器发送回来,以json的格式展示在浏览器中。

处理通过?携带的键值对形式参数,url还可以携带动态参数/:id,此处以:表示后面是一个动态参数,这个路径可以匹配任意一个字符串。

如果需要得到这个动态参数,就需要req.params对象,其存储了动态参数。

app.get('/user/:id', (req, res) => {res.send(req.params)
})

在指定路径时,以:id结尾,表示这个路径可以匹配一个动态参数,参数名为id。动态参数存储在req.params中,直接把这个对象返回给浏览器。

访问/user/:115599

在这里插入图片描述

req.params拿到了动态参数id = 115599

匹配多个动态参数:

app.get('/user/:id/:name', (req, res) => {res.send(req.params)
})

此处匹配两个动态参数idname

在这里插入图片描述


静态资源托管

当网站中有多个htmlcssjs文件,此时如果一个个完成get方法会很麻烦。为此express提供了一个express.static方法,它可以快速创建一个静态资源服务器,指定一个目录作为根目录,该目录下的所有文件都可以直接进行访问。

语法:

app.use(express.static(目录路径))

首先通过express.static指定一个目录,此时该目录下的所有资源都可以被访问。再将返回值作为app.use的参数传入,此时就完成了静态资源托管。

示例:

const express = require('express')
const path = require('path')const app = express()
app.use(express.static(path.join(__dirname, "/root")))app.listen(80, () => {console.log("success!")
})

此处引入了一个path模块,防止路径错误。express.static指定同级目录下的/root目录作为服务的根目录,该目录下有index.html style.css两个文件。

在浏览器中访问这两个文件:

在这里插入图片描述

两个文件都可以直接访问,虽然没有写app.get("/root/index.html")这样的方法,但是通过静态资源托管,就直接可以进行访问了。

托管多个资源

如果需要同时托管多个目录下的静态资源,可以多次执行app.use(express.static(目录路径))

app.use(express.static("./public"))
app.use(express.static("./files"))

这样publicfiles两个目录下的文件,都被托管了。浏览器请求文件时,按照托管的顺序查询,假设两个目录内部都有index.html,由于public先托管,浏览器会得到public/index.html

挂载路径前缀

在静态资源托管指定目录后,目录内部的文件可以直接被访问,无需指明该文件在哪一个目录下。

app.use(express.static("./public"))

比如以以上形式托管静态资源,最终访问服务器就以127.0.0.1/index.html即可,public目录不会出现在路径中,如果访问127.0.0.1/public/index.html反而会出错,找不到路径。

如果希望用户访问静态资源时,要加上这个路径前缀,那么可以在app.use时添加一个路径前缀。

app.use(`/public`, express.static("./public"))

此时就可以通过127.0.0.1/public/index.html进行访问了。当然也不一定说前面这个路径前缀一定要和托管的目录名称相同,可以自己指定:

app.use(`/abc`, express.static("./public"))

这样就可以通过127.0.0.1/abc/index.html访问资源。

之前说过,在多个目录被托管时,如果有同名文件,就会发生覆盖,只能访问到先托管那个目录下的文件。如果加上路径前缀,就可以解决这个问题:

app.use("/public", express.static("./public"))
app.use("/files", express.static("./files"))

想要访问两个不同的index.html,只需要加上不同的前缀即可:

127.0.0.1/public/index.html
127.0.0.1/files/index.html

路由

Express要为每一种类型的请求,都绑定一个函数来处理。当Express收到一个请求,就会进行匹配,找到对应的函数,然后执行,这个过程就是路由

在这里插入图片描述

路由分为三部分:请求类型url处理函数

上图中有三个路由,其中第一个路由请求的地址是/与后两者不同。虽然后两个路由请求的都是/index.html,但是它们请求的方法不同。

当一个请求到来,Express会进行路由匹配,找到请求类型url都相同的函数,然后执行它。

当一个路由绑定了多个函数,只有第一个生效

app.get('/', (req, res) => {res.send("func1")
})app.get('/', (req, res) => {res.send("func2")
})

以上代码,为get /绑定了两个函数,此时由于func1先定义,只有func1会生效。


模块化

先前的所有路由,都是直接挂载到app这个对象上的,其实Express并不建议这么做,而是建议将路由单独做成一个模块。

模块化路由流程:

  1. 创建一个新模块(.js文件)
  2. 调用express.Router方法创建路由对象
  3. 往路由对象上挂载路由
  4. 使用module.exports向外共享路由
  5. 使用app.use注册路由模块

示例:

以下操作均在router.js模块中。

创建路由对象:

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

路由对象是express的一个对象,专门用于挂载路由。

挂载路由:

router.get('/', function(req, res){res.send("get / success")
})router.post('/', function(req, res){res.send("post / success")
})router.get('/index.html', function(req, res){res.send("get /index.html success")
})

此时直接把路由挂载到router对象上,而不是app对象上。

使用module.exports向外共享路由:

module.exports = router

此时一个路由模块就制作完成了,要注意不能写为exports = router,因为这样会导致exportsmodule.exports指向不同对象,最后没有成功共享router

main.js中导入模块:

const express = require('express')
const router = require('./router.js')
const app = express()

注册路由:

app.use(router)

直接将路由对象通过use注册到app中。

路由和静态资源托管一样,都是通过app.use进行绑定的,那么路由自然也可以增加路径访问前缀:

app.use('/test', router)

这样访问路由内部的所有路径时,都要先加上前缀/test


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

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

相关文章

TensorRT-LLM的k8s弹性伸缩部署方案

Scaling LLMs with NVIDIA Triton and NVIDIA TensorRT-LLM Using Kubernetes | NVIDIA Technical Blog 一共涉及4个k8s组件: 1. Deployment:跑起来N个pod;指定NVIDIA官方的triton&trt-llm的docker image,指定好model放在哪个…

6.0、静态路由

路由器最主要的功能就是转发数据包。路由器转发数据包时需要查找路由表(你可以理解为地图),管理员可以直接手动配置路由表,这就是静态路由。 1.什么是路由? 在网络世界中,路由是指数据包在网络中的传输路…

4. 类和对象(下)

1. 初始化列表 • 之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅ 式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成 员列表&#xff0c…

AI驱动的医疗创新:信息抽取与知识图谱在临床应用中的转变

一、思通数科平台支持多种输入格式,如电子病历、临床数据和医学文献等,并能将这些信息快速转换为结构化数据,包括自动360度不同角度的旋转识别,提升数据的可操作性和可检索性。通过我们的解决方案,医疗机构能够有效整合…

线程的joinable属性,以及主线程出现异常时,对其等待应该进行的处理

在C多线程编程中,线程的 joinable 属性是一个重要的概念,用于判断线程是否可以调用 join() 或 detach() 方法。当线程已经调用过 join() 或 detach() 之后,它将不再 joinable,此时调用 join() 或 detach() 会导致程序崩溃。 此外…

关注!这些型号SSD有Windows蓝屏问题需要修复

近期,在闪迪官方有一个SSD FW升级提醒,主要是为了解决Windows 11 24H2系统蓝屏的问题: Fix问题:这些SSD的主机内存缓冲区(Host Memory Buffer,简称HMB)功能可能会导致系统出现蓝屏死机&#xff…

Rust 力扣 - 1461. 检查一个字符串是否包含所有长度为 K 的二进制子串

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 长度为k的二进制子串所有取值的集合为[0, sum(k)]&#xff0c;其中sum(k)为1 2 4 … 1 << (k - 1) 我们只需要创建一个长度为sum(k) 1的数组 f &#xff0c;其中下标为 i 的元素用来标记字符串中子串…

xtu oj 连接字符串

文章目录 回顾思路代码 回顾 AB III问题 H: 三角数问题 G: 3个数等式 数组下标查询&#xff0c;降低时间复杂度1405 问题 E: 世界杯xtu 数码串xtu oj 神经网络xtu oj 1167 逆序数&#xff08;大数据&#xff09;xtu oj 原根xtu oj 不定方程的正整数解xtu oj 最多的可变换字符串…

gradle的安装及其配置

1、下载网址 Gradle | Releases 2、 3、配置环境变量 4、 5、cmd输入gradle-v查看版本

数据结构与算法基础总结

为什么学习数据结构与算法&#xff1f; 关于数据结构和算法&#xff0c;以前只是看过一些零散的文章或者介绍&#xff0c;从来都没有系统的去学习过。随着工作之余&#xff0c;看了几本书&#xff0c;读了一些高质量的专栏&#xff0c;也接触了一些有关梦想的故事&#xff0c;发…

使用Docker Swarm进行集群管理

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Docker Swarm进行集群管理 引言 Docker Swarm 简介 安装 Docker Ubuntu CentOS 初始化 Swarm 集群 加入 Worker 节点 验证集…

Rust 力扣 - 643. 子数组最大平均数 I

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历长度为k的窗口&#xff0c;我们只需要记录窗口内的最大和即可&#xff0c;遍历过程中刷新最大值 结果为窗口长度为k的最大和 除以 k 题解代码 impl Solution {pub fn find_max_average(nums: Vec<…

ssm+jsp662教务信息平台的设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php phython node.js uniapp 微信小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不…

LDA 线性分类

线性判别分析是一种经典的线性分类方法&#xff0c;将高维空间投射到低维空间&#xff0c;如下图。 LDA 的目标就是简单累内距离变小&#xff0c;把类间的距离变大&#xff0c;这样就可以把相似的数据聚集在一起。 u1 和 u2 类间距离&#xff0c;S1、S2 为类内数据点之间的距…

智能离线语音识别不灵敏?如何改善和提升识别率?

前言 有用户反馈离线语音识别不灵敏&#xff0c;跟着笔者一起分析原因吧。笔者知识能力有限&#xff0c;难免会误&#xff0c;还请大家批评指正。 1 影响离线语音识别的因素 笔者分析离线语音识别不灵敏的原因有以下几点 1.1 运行硬件的算力限制 由于离线语音识别在本地MCU…

贪心算法---java---黑马

贪心算法 1)Greedy algorithm 称之为贪心算法或者贪婪算法&#xff0c;核心思想是 将寻找最优解的问题分为若干个步骤每一步骤都采用贪心原则&#xff0c;选取当前最优解因为未考虑所有可能&#xff0c;局部最优的堆叠不一定得到最终解最优 贪心算法例子 Dijkstra while …

使用Docker Compose搭建多服务应用

使用Docker Compose搭建多服务应用 Docker Compose简介 安装Docker Compose 在Linux上安装Docker Compose 在macOS上安装Docker Compose 在Windows上安装Docker Compose 创建项目结构 Flask应用 安装依赖 Dockerfile 配置Docker Compose 构建和运行应用 访问应用 高级配置 环…

【教程】Git 标准工作流

前言 Git 是日常开发中常用的版本控制工具&#xff0c;配合代码托管仓库&#xff08;如&#xff0c;Github&#xff0c;GitLab&#xff0c;Gitee 等&#xff09;用来实现多人多版本的协作开发。 但是 Git 的命令纷繁复杂&#xff0c;多如累卵&#xff0c;不可能也不需要全部搞…

Vue 3 Vite 项目打包优化:自动删除指定文件的方法

程序员必备宝典https://tmxkj.top/#/ 在 Vue 3 项目中&#xff0c;如果你需要在打包之前删除指定的文件&#xff0c;可以使用 Node.js 的 fs 模块来实现。这可以通过在 vue.config.js 文件中配置一个自定义的 Webpack 插件来完成。 1.安装必要的依赖&#xff08;如果还没…

前端通过nginx部署一个本地服务的方法

前端通过nginx部署一个本地服务的方法&#xff1a; 1.下载ngnix nginx 下载完成后解压缩后运行nginx.exe文件 2.打包你的前端项目文件 yarn build 把生成的dist文件复制出来&#xff0c;替换到nginx的html文件下 3.配置conf目录的nginx.conf文件 主要配置server监听 ser…