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.rhkb.cn/news/467172.html

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

相关文章

知识中台赋能法律咨询服务:八大核心优势

法律咨询服务领域,知识中台以其独特的功能和优势,为行业发展注入了新的活力。以下是知识中台在法律咨询服务中展现的八大核心优势: 一、法律知识资源的全面整合 知识中台致力于收集、整理和整合各类法律知识资源,包括法律法规、…

【青牛科技】GC5931:工业风扇驱动芯片的卓越替代者

在工业领域,工业风扇的稳定高效运行对于维持良好的生产环境至关重要。而驱动芯片作为工业风扇控制系统的核心元件,其性能直接影响风扇的工作状态。芯麦 GC5931 作为一款新型驱动芯片,在替代 A5931/Allegro 应用于工业风扇中展现出了非凡的优势…

使用Netty实现一个简单的聊天服务器

✅作者简介:热爱Java后端开发的一名学习者,大家可以跟我一起讨论各种问题喔。 🍎个人主页:Hhzzy99 🍊个人信条:坚持就是胜利! 💞当前专栏:Netty 🥭本文内容&a…

【HarmonyOS】鸿蒙应用低功耗蓝牙BLE的使用心得 (二)

【HarmonyOS】鸿蒙应用低功耗蓝牙BLE的使用心得 (二) 一、前言 目前鸿蒙应用的实现逻辑,基本都是参考和移植Android端来实现。针对BLE低功耗蓝牙来说,在鸿蒙化的实现过程中。我们发现了,鸿蒙独有的优秀点&#xff0c…

第六十三周周报 GCN-CNNGA

文章目录 week 63 GCN-CNNGA摘要Abstract1. 题目2. Abstract3. 文献解读3.1 Introduction3.2 创新点 4. 网络结构4.1 数据分析4.2 混合深度学习框架的发展4.3 Mul4.4 CNN block4.5 GCN block4.6 GRU block4.7 注意力机制4.8 模型评估标准 5. 实验结果5.1 不同邻接矩阵的性能评价…

geoserver+postgis 最短路径规划常见问题记录

一、说明 具体实现步骤可参考其他博文,下面的这个博主写的很详细,步骤很清晰,注释也很全。geoserverpostgis 最短路径规划_geoserver 最短路径 存储过程-CSDN博客 本次文章,仅记录过程中需要注意的方面。 二、数据预处理 目标&a…

石油安全理论知识题库 考试宝在线刷题

一、单选题(每题有4个选项,其中只有1个是正确的,将正确的选项号填入括号内) 1.新修订的《中华人民共和国安全生产法》于( )正式实施。 A、2014年1月1日 B、2014年12月1日 C、2015年1月1日 D、2015年…

航空标志灯技术革新:提升夜间飞行安全

航空标志灯 随着低空飞行活动的增多和新型飞行器(如无人机、热气球和直升机)的普及,地面重要设施的安全面临前所未有的挑战。因此,航空标志灯的安装变得尤为重要。它们通过提升城市天际线、广袤乡村、跨河桥梁及电力网络等复杂地…

前后端交互接口(三)

前后端交互接口(三) 前言 前两集我们先做了前后端交互接口的约定以及浅浅的阅读了一些proto代码。那么这一集我们就来看看一些重要的proto代码,之后把protobuffer给引入我们的项目当中! gateway.proto 我们来看一眼我们的网关…

机器学习—sigmoid的替代品

Z状结肠激活函数,在隐藏层中,在输出层,因为用逻辑回归建立神经网络,创造了大量的逻辑回归单元,但是如果你使用其他激活函数,神经网络可以变得更加强大。 以需求预测为例,给定价格,航…

数据分析-44-时间序列预测之深度学习方法TCN

文章目录 1 TCN简介1.1 网络示意图1.2 TCN优点2 模拟应用2.1 模拟数据2.2 预处理创建滞后特征2.3 划分训练集和测试集2.4 创建TCN模型2.5 模型训练2.6 模型预测3 自定义my_TCN模型3.1 my_TCN()函数3.2 训练模型3.3 模型预测3.4 改进4 参考附录1 TCN简介 时间卷积网络(TCN)是…

2024最新AI绘画系统软件(Midjourney)+GPT4文档分析总结,多模态识图理解,AI文生图/图生图/混图生图(图像混合)

一、前言 人工智能的快速发展已成为全球关注的焦点,其应用领域广泛,涵盖绘图、语言处理、视频编辑等。前沿技术不仅推动科技创新,还在艺术创作、内容生产和商业实践等方面展示出巨大潜力。例如,AI语言模型显著提升了内容自动生成、…

input file检验成功之后才可以点击

input file检验成功之后才可以点击 需求 在上传发票前需要先填写发票号,然后点击选择文件直接完成上传功能 实现思路 在没有输入发票号之前,file按钮不可用不能点击,输入之后,按钮可用,点击之后选择文件&#xff…

每日OJ题_牛客_AB31活动安排_区间贪心_C++_Java

目录 牛客_AB31活动安排_区间贪心 题目解析 C代码 Java代码 牛客_AB31活动安排_区间贪心 活动安排_牛客题霸_牛客网 描述: 给定n个活动,每个活动安排的时间为[ai,bi)。求最多可以选择多少个活动,满足选择的活动时间两两之间没有重合。 …

购物车-多元素组合动画css

学习 渡一课程 多元素组合动画 练习。 在我们开发购物车功能时,经常会有点击添加按钮,就会有一个小圆点掉进购物车的动画,如下图所示,今天我们通过css来实现。 首先实现多元素组合动画 直接上代码,可以复制到本地使用…

深度学习:bert模型

multi-headed机制 1、通过不同的head得到多个特征表达,一般8个head 2、将所有特征拼接在一起 3、降维,将Z0~Z7连接一个FC全连接实现降维 多层堆叠 位置编码 如何实现位置编码? (1)为每个时间步添加一个0-1范围内的数…

Android Glide动态apply centerCropTransform(),transition withCrossFade动画,Kotlin

Android Glide动态apply centerCropTransform(),transition withCrossFade动画,Kotlin import android.graphics.Bitmap import android.os.Bundle import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import com.bumptech.glide.Glide import …

Vue 组件通信-自定义事件(七)

一、组件自定事件概念 自己定义的事件,包含事件名,事件回调等,定义好之后去给组件使用。也是一种组件的通信方式,适用于子组件传递给父组件。 二、 组件自定义事件实现子传父 1、在父组件中给子组件绑定一个自定义事件 在子组件标…

计算机的错误计算(一百四十八)

摘要 本节探讨 MATLAB 中 附近数的正割函数与 附近数的余割函数的计算精度问题。 例1. 已知 计算 直接贴图吧: 另外,16位的正确值分别为 0.4105556037464873e9、0.3670813182326778e13、-0.2549029285657875e8 与 -0.1248777628817462e12&am…

《XGBoost算法的原理推导》12-14决策树复杂度的正则化项 公式解析

本文是将文章《XGBoost算法的原理推导》中的公式单独拿出来做一个详细的解析,便于初学者更好的理解。 我们定义一颗树的复杂度 Ω Ω Ω,它由两部分组成: 叶子结点的数量;叶子结点权重向量的 L 2 L2 L2范数; 公式(…