Node.js:Express 服务 路由

news2024/11/25 18:46:39

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.coloradmin.cn/o/2232179.html

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

相关文章

C语言 | Leetcode C语言题解之第530题二叉搜索树的最小绝对差

题目: 题解: void dfs(struct TreeNode* root, int* pre, int* ans) {if (root NULL) {return;}dfs(root->left, pre, ans);if (*pre -1) {*pre root->val;} else {*ans fmin(*ans, root->val - (*pre));*pre root->val;}dfs(root->…

重学SpringBoot3-整合 Elasticsearch 8.x (二)使用Repository

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 整合 Elasticsearch 8.x (二)使用Repository 1. 环境准备1.1 项目依赖1.2 Elasticsearch 配置 2. 使用Repository的基本步骤2.1 创建实体类2.2 创…

SpringBoot源码(四):run() 方法解析(一)

run()方法: public ConfigurableApplicationContext run(String... args) {// 记录应用启动时间long startTime System.nanoTime();DefaultBootstrapContext bootstrapContext createBootstrapContext();// 创建 ConfigurableApplicationContext 对象Configurabl…

ASP .NET CORE 6 在项目中集成WatchDog开源项目

概念 WatchDog是一个开源的项目,可以实现对.Net 应用程序和API实现实时应用日志和性能监控平台。可以实现实时记录和查看应用程序中的消息、事件、HTTP请求和响应,以及运行时捕获的异常,有效帮助开发人员去排查应用异常,提升开发效…

分类算法——决策树 详解

决策树的底层原理 决策树是一种常用的分类和回归算法,其基本原理是通过一系列的简单决策,将数据集划分为多个子集,从而实现分类。决策树的核心思想是通过树形结构表示决策过程,节点代表特征,边代表决策,叶子…

python 使用进程池并发执行 SQL 语句

这段代码使用了 Python 的 multiprocessing 模块来实现真正的并行处理,绕过 Python 的全局解释器锁(GIL)限制,从而在多核 CPU 上并发执行多个 SQL 语句。 from pyhive import hive import multiprocessing# 建立连接 conn hive.…

[ 问题解决篇 ] win11中本地组策略编辑器gpedit.msc打不开(gpedit.msc缺失)

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…

[Python学习日记-55] 软件开发目录设计规范

[Python学习日记-55] 软件开发目录设计规范 简介 为什么要设计好目录结构? 目录组织方式 关于 README 的内容 关于 setup.py 和 requirements.txt 关于配置文件的使用方法 简介 我们在浏览一些开源项目或者是一些安装后的软件的时候会发现,不同的两…

18.农产品销售系统(基于springboot和vue的Java项目)

目录 1.系统的受众说明 2.开发环境与技术 2.1 Java语言 2.2 MYSQL数据库 2.3 IDEA开发工具 2.4 Spring Boot框架 3.系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 系统流程 3.2.1 操作流程 3.2.2 登录流程 3.2.3 删除信…

嵌入式常用功能之通讯协议1--IIC

嵌入式常用功能之通讯协议1--串口 嵌入式常用功能之通讯协议1--IIC(本文) 嵌入式常用功能之通讯协议1--SPI 一、IIC总线协议介绍 Inter-Integrated Circuit(集成电路总线),是由 Philips 半导体公司(现在的 NXP 半导体…

一位纯理科生,跨界自学中医,自行组方治好胃病、颈椎病与高血脂症,并在最权威的中国中医药出版社出版壹本专业中医图书!

这是一位铁杆中医迷, 也是《神农本草经——精注易读本》的作者。 希望更多的人能够受到启发,感受中医之神奇,敢于跨界,爱好中医,学习中医! 一个病人以自己的切身感受与诊断,并使之汤药治愈疾病&…

java项目之个人博客系统的设计与实现(springboot)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的闲一品交易平台。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: springboot个人博客系统的…

使用 Sortable.js 库 实现 Vue3 elementPlus 的 el-table 拖拽排序

文章目录 实现效果Sortable.js介绍下载依赖添加类名导入sortablejs初始化拖拽实例拖拽完成后的处理总结 在开发过程中,我们经常需要处理表格数据,并为用户提供便捷的排序方式。特别是在需要管理长列表、分类数据或动态内容时,拖拽排序功能显得…

使用Kafka构建大规模消息传递系统

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用Kafka构建大规模消息传递系统 引言 Kafka 简介 安装 Kafka 创建主题 生产者 消费者 高级特性 分区 持久化 消费者组 消息确认…

队列(Queue)的介绍与实现

文章目录 队列队列的概念及结构 队列的实现初始化队列销毁队列队尾入队列队头出队列获取队列头部元素检测队列是否为空获取队列中有效元素个数 队列 队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表。队列遵…

【大模型之Graph RAG系列之二】对比传统RAG技术中使用的向量搜索技术,知识图谱有哪些优缺点?

向量搜索和知识图谱是两项用于改善搜索体验的重要技术。结合这两种技术形成的Graph RAG可以进一步提高搜索的准确性和上下文相关性。本文将深入对比向量搜索和知识图谱,让读者快速了解这两种技术的原理及优缺点,以便于将来的技术决策。 向量搜索 向量搜…

电赛入门之软件stm32keil+cubemx

hal库可以帮我们一键生成许多基本配置,就不需要自己写了,用多了hal库就会发现原来用基本库的时候都过的什么苦日子(笑 下面我们以f103c8t6,也就是经典的最小核心板来演示 一、配置工程 首先来新建一个工程 这里我们配置rcc和sys&…

从“技术深耕”到“品牌绽放”,解码遨游通讯的高成长路径!

在粤港澳大湾区这片充满活力的土地上,科技创新正以前所未有的速度推动着各行各业的发展。在这样一个充满机遇与挑战的环境中,遨游通讯以其在危险作业场景和应急救援场景中提供的定制化智能终端解决方案,脱颖而出,成为危急特赛道的…

golang通用后台管理系统02(RSA加密解密,登录密码加密解密)

参考:https://blog.csdn.net/lady_killer9/article/details/118026802 1.加密解密工具类PasswordUtil.go package utilimport ("crypto/rand""crypto/rsa""crypto/x509""encoding/pem""fmt""log"&qu…

【HarmonyOS NEXT】在 HarmonyOS NEXT 中实现优雅的加载动画

【HarmonyOS NEXT】在 HarmonyOS NEXT 中实现优雅的加载动画 在移动应用开发中,加载动画是提升用户体验的重要工具。在应用程序处理数据或加载页面时,为用户提供视觉反馈尤为关键。在这篇博客中,我们将探讨如何在 HarmonyOS NEXT 中使用 Sta…