【Node.js工程师养成计划】之express框架

news2024/11/24 13:17:10

一、Express

官网:http://www.expressjs.com.cn

express 是一个基于内置核心 http 模块的,一个第三方的包,专注于 web 服务器的构建。

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

使用 Express 可以快速地搭建一个完整功能的网站。

Express 框架核心特性:

  • 可以设置中间件来响应 HTTP 请求。

  • 定义了路由表用于执行不同的 HTTP 请求动作。

  • 可以通过向模板传递参数来动态渲染 HTML 页面。

Express适合做什么

  • 传统web网站
  • API接口服务器
  • 服务端渲染中间层
  • 开发辅助工具
  • 自定义集成框架

二、Express项目构建

npm init -y
npm install express --save
npx express-generator

使用 npx express-generator 命令可以自动创建一个包含所有基本目录和文件的 Express.js 应用模板,这样开发者就可以直接开始编写业务代码,而不需要从零开始设置项目结构。
这个生成的项目通常包括以下部分:

  • bin 目录:存放可执行文件,包括启动应用的脚本。
  • public 目录:用于存放静态文件,如图片、JavaScript 和 CSS 文件。
  • routes 目录:存放路由文件,定义应用的路由逻辑。
  • views 目录:存放视图文件,通常是模板文件,用于生成 HTML 响应。
  • app.js:应用的主入口文件,配置中间件、路由等。
    在这里插入图片描述

三、express框架的基本使用

// 引入express
const express = require('express')
// 创建应用对象
const app = express();

app.get('/', function(req, res){
  // 响应消息内容
  res.send('全体起立!')
})
 
// 监听服务
app.listen(4000, () => {
  console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
request 和 response 对象的具体介绍:

Request 对象 - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。常见属性有:

req.app:当callback为外部文件时,用req.app访问express的实例
req.baseUrl:获取路由当前安装的URL路径
req.body / req.cookies:获得「请求主体」/ Cookies
req.fresh / req.stale:判断请求是否还「新鲜」
req.hostname / req.ip:获取主机名和IP地址
req.originalUrl:获取原始请求URL
req.params:获取路由的parameters
req.path:获取请求路径
req.protocol:获取协议类型
req.query:获取URL的查询参数串
req.route:获取当前匹配的路由
req.subdomains:获取子域名
req.accepts():检查可接受的请求的文档类型
req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
req.get():获取指定的HTTP请求头
req.is():判断请求头Content-Type的MIME类型

Response 对象 - response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据。常见属性有:

res.app:同req.app一样
res.append():追加指定HTTP头
res.set()在res.append()后将重置之前设置的头
res.cookie(name,value [,option]):设置Cookie
opition: domain / expires / httpOnly / maxAge / path / secure / signed
res.clearCookie():清除Cookie
res.download():传送指定路径的文件
res.get():返回指定的HTTP头
res.json():传送JSON响应
res.jsonp():传送JSONP响应
res.location():只设置响应的Location HTTP头,不设置状态码或者close response
res.redirect():设置响应的Location HTTP头,并且设置状态码302
res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
res.send():传送HTTP响应
res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
res.set():设置HTTP头,传入object可以一次设置多个头
res.status():设置HTTP状态码
res.type():设置Content-Type的MIME类型

四、Express管理用户数据信息

项目目录:
在这里插入图片描述
db.json

{
  "users": [
    {
      "id": 1,
      "username": "Monica",
      "age": "22"
    },
    {
      "id": 2,
      "username": "Alen",
      "age": "26"
    }
  ],
  "video": []
}
// 引入express
const express = require('express')
const fs = require('fs');
const { json } = require('stream/consumers');
// 创建应用对象
const app = express();

app.get('/', function(req, res){
  fs.readFile('./db.json', 'utf-8',(err, data) => {
    if (!err) {
      const back = JSON.parse(data)
      res.send(back.users)
    } else {
      res.status(500).json({err})
    }
  })
})
 
// 监听服务
app.listen(4000, () => {
  console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
在这里插入图片描述
可以使用apifox去管理接口
在这里插入图片描述
解决回调地狱问题:

// 引入express
const express = require('express')
const fs = require('fs');
const { promisify } = require('util')
const readFile = promisify(fs.readFile)

// 创建应用对象
const app = express();

app.get('/', async function(req, res){
  try {
    let back = await readFile('./db.json', 'utf-8')
    res.send(JSON.parse(back))
  } catch (err) {
    res.status(500).json({err})
  }
})
 
// 监听服务
app.listen(4000, () => {
  console.log('run http://127.0.0.1:4000');
})

五、处理客户端Post请求数据

// 引入express
const express = require('express')
const fs = require('fs');
const { promisify } = require('util')
const readFile = promisify(fs.readFile)

// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())

app.get('/', async function(req, res){
  try {
    let back = await readFile('./db.json', 'utf-8')
    res.send(JSON.parse(back))
  } catch (err) {
    res.status(500).json({err})
  }
})

app.post('/', async (req, res) => {
  console.log(req.headers)
  console.log(req.body)
})
 
// 监听服务
app.listen(4000, () => {
  console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
app.use(express.urlencoded()) 是 Express 框架中的一个中间件,用于解析来自客户端的 URL 编码的请求体数据,并将其转换为 JavaScript 对象。这通常用于处理 POST 请求中的表单数据。使用这个中间件后,你可以在路由处理程序中通过 req.body 来访问表单数据。
app.use(express.json()) 来解析 JSON 格式的请求体数据

六、添加用户信息到db文件

拿到提交的表单值:

// 引入express
const express = require('express')
const fs = require('fs');
const { promisify } = require('util')
const readFile = promisify(fs.readFile)

// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())

app.get('/', async function(req, res){
  try {
    let back = await readFile('./db.json', 'utf-8')
    res.send(JSON.parse(back))
  } catch (err) {
    res.status(500).json({err})
  }
})

app.post('/', async (req, res) => {
  console.log(req.headers)
  // console.log(req.body)

  let body = req.body
  if (!body) {
    res.status(403).json({
      err: '缺少用户信息'
    })
  }
  let back = await readFile('./db.json', 'utf-8')
  const jsonObj = JSON.parse(back)
  // 给输入的用户信息添加个id
  body.id = jsonObj.users[jsonObj.users.length-1].id + 1
  jsonObj.users.push(body)
  console.log(body);

  res.send(body)
})
 
// 监听服务
app.listen(4000, () => {
  console.log('run http://127.0.0.1:4000');
})

文件写入:

// 引入express
const express = require('express')
const fs = require('fs');
const { promisify } = require('util')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)

// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())

app.get('/', async function(req, res){
  try {
    let back = await readFile('./db.json', 'utf-8')
    res.send(JSON.parse(back))
  } catch (err) {
    res.status(500).json({err})
  }
})

app.post('/', async (req, res) => {
  console.log(req.headers)
  // console.log(req.body)

  let body = req.body
  if (!body) {
    res.status(403).json({
      err: '缺少用户信息'
    })
  }
  let back = await readFile('./db.json', 'utf-8')
  const jsonObj = JSON.parse(back)
  // 给输入的用户信息添加个id
  body.id = jsonObj.users[jsonObj.users.length-1].id + 1
  jsonObj.users.push(body)
  // 写入文件
  try{
    let w = await writeFile('./db.json', JSON.stringify(jsonObj))
    if(!w){
      res.status(200).send({
        msg: '添加成功'
      })
    }
  } catch(err){
    res.status(500).json({err})
  }
})
 
// 监听服务
app.listen(4000, () => {
  console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
逻辑抽离:
db.js

const { promisify } = require('util')
const fs = require('fs')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)

exports.getDb = async () => {
  let data = await readFile('./db.json', 'utf-8')
  return JSON.parse(data)
}

exports.serveDb = async (data) => {
  return await writeFile('./db.json', JSON.stringify(data))
}

app.js

// 引入express
const express = require('express')
const db = require('./db')



// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())

app.get('/', async function(req, res){
  try {
    let back = await db.getDb()
    res.send(back)
  } catch (err) {
    res.status(500).json({err})
  }
})

app.post('/', async (req, res) => {
  // console.log(req.headers)
  // console.log(req.body)

  let body = req.body
  if (!body) {
    res.status(403).json({
      err: '缺少用户信息'
    })
  }
  let back = await db.getDb()
  const jsonObj = back
  // 给输入的用户信息添加个id
  body.id = jsonObj.users[jsonObj.users.length-1].id + 1
  jsonObj.users.push(body)
  // 写入文件
  try{
    let w = await db.serveDb(jsonObj)
    console.log(111, w)
    if(!w){
      res.status(200).send({
        msg: '添加成功'
      })
    }
  } catch(err){
    res.status(500).json({err})
  }
})
 
// 监听服务
app.listen(4000, () => {
  console.log('run http://127.0.0.1:4000');
})

七、修改用户信息

// 引入express
const express = require('express')
const db = require('./db')



// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())

app.get('/', async function(req, res){
  try {
    let back = await db.getDb()
    res.send(back)
  } catch (err) {
    res.status(500).json({err})
  }
})

app.post('/', async (req, res) => {
  // console.log(req.headers)
  // console.log(req.body)

  let body = req.body
  if (!body) {
    res.status(403).json({
      err: '缺少用户信息'
    })
  }
  let back = await db.getDb()
  const jsonObj = back
  // 给输入的用户信息添加个id
  body.id = jsonObj.users[jsonObj.users.length-1].id + 1
  jsonObj.users.push(body)
  // 写入文件
  try{
    let w = await db.serveDb(jsonObj)
    if(!w){
      res.status(200).send({
        msg: '添加成功'
      })
    }
  } catch(err){
    res.status(500).json({err})
  }
})

app.put('/:id', async (req, res) => {
  // console.log(req.params.id) // 传进来的数据
  // console.log(req.body)
  try{
    let userInfo = await db.getDb()
    let userId = Number(req.params.id)
    let user = userInfo.users.find(item => item.id === userId)
    if (!user){
      res.status(403).send({
        msg: '用户不存在'
      })
    }
    const body = req.body
    user.username = body.username ? body.username : user.username
    user.age = body.age ? body.age : user.age
    userInfo.users[userId - 1] = user
    let w = await db.serveDb(userInfo)
    if (!w) {
      res.status(201).send({
        msg: '修改成功'
      })
    }
  } catch(err){
    res.status(500).json({err})
  }
})
 
// 监听服务
app.listen(4000, () => {
  console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
在这里插入图片描述

八、学到这里,感觉nodeJS还挺有意思的

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

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

相关文章

LabVIEW机械臂控制与图像处理示教平台

LabVIEW机械臂控制与图像处理示教平台 随着工业自动化技术的快速发展,工业机器人在制造业中的应用越来越广泛,它们在提高生产效率、降低人工成本以及保证产品质量方面发挥着重要作用。然而,传统的工业机器人编程和操作需要专业知识&#xff…

React正式更新!开始学习React 19!

本文为原创文章,原文链接:J实验室,未经授权请勿转载 今年2月份,React 发布消息确认今年发布 v19 版本,尘封两年的版本号终于要更新了(详情点击:React 19 发布在即,抢先学习一下新特性…

FSNotes for Mac v6.7.1中文激活版:强大的笔记管理工具

FSNotes for Mac是一款功能强大的文本处理与笔记管理工具,为Mac用户提供了一个直观、高效的笔记记录和整理平台。 FSNotes for Mac v6.7.1中文激活版下载 FSNotes支持Markdown语法,使用户能够轻松设置笔记格式并添加链接、图像等元素,实现笔记…

Linux下启动jenkins报错问题解决

jenkins端口报错 java.io.IOException: Failed to start Jettyat winstone.Launcher.<init>(Launcher.java:209)at winstone.Launcher.main(Launcher.java:496)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.int…

【氮化镓】AlGaN/GaN HEMTs沟道温度测量

文章是关于AlGaN/GaN HEMTs&#xff08;高电子迁移率晶体管&#xff09;在不同基底&#xff08;如蓝宝石和硅&#xff09;上生长时&#xff0c;通过直流&#xff08;DC&#xff09;特性方法确定沟道温度的研究。文章由J. Kuzmk, P. Javorka, A. Alam, M. Marso, M. Heuken, 和 …

微软如何打造数字零售力航母系列科普04 - 微软联合Adobe在微软365应用程序中工作时推出新的生成式AI功能

微软和Adobe正在合作&#xff0c;将情境营销见解和工作流程引入微软Copilot&#xff0c;以提供生成的人工智能功能&#xff0c;使营销人员和营销团队能够在自然的工作流程中实现更多目标。 这些新的集成功能将在生产力和协作工具&#xff08;如Outlook、Teams和Word&#xff0…

JAVA基础——集合框架(List与Set)

数据结构 什么是数据结构 数据结构就是用来装数据以及数据与之间关系的一种集合。如何把相关联的数据存储到计算机&#xff0c;为后续的分析提供有效的数据源&#xff0c;是数据结构产生的由来。数据结构就是计算机存储、组织数据的方式。好的数据结构&#xff0c;让我们做起事…

使用QT完成如图的游戏登录界面 使用信号和槽完成密文明文密码转换,重置账号和密码,登录校验 详细代码在主页下载

头文件: #ifndef LOGINWIDGET_H #define LOGINWIDGET_H #include <QLineEdit> #include <QPushButton> #include <QWidget> class LoginWidget : public QWidget {Q_OBJECT public: LoginWidget(QWidget *parent = 0); ~LoginWidget(); public slots: …

基于uniapp+微信小程序的智能停车场管理小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Three.js杂记(十五)—— 汽车展览(下)

在上一篇文章Three.js杂记&#xff08;十四&#xff09;—— 汽车展览上 - 掘金 (juejin.cn)中主要对切换相机不同位置和鼠标拖拽移动相机焦点做了简单的应用。 那么现在聊聊该如何实现汽车模型自带的三种动画展示了&#xff0c;实际上可以是两种汽车前后盖打开和汽车4车门打开…

C# APS.NET CORE 6.0 WebApi在IIS部署报错

今天尝试着把基于 APS.NET CORE6.0开发的webAPI程序部署到IIS中&#xff0c;当打开网站地址时报错&#xff0c;无法打开&#xff0c;于是查找资料最终进行了解决。 打开 IIS →模块 查看列表中是否存在 AspNetCoreModuleV2&#xff0c;如下&#xff1a; 对应的应用池需要选择“…

小程序SSL证书更新指南

随着网络技术的不断发展&#xff0c;小程序已经成为许多企业和个人进行业务推广和服务提供的重要平台。在享受小程序带来的便利和高效的同时&#xff0c;我们也必须重视其安全性问题。SSL证书作为保障小程序数据传输安全的重要手段&#xff0c;其更新工作不容忽视。本文将为大家…

Android log tag标签如am_pss意义

Android log tag标签如am_pss意义 Android输出日志中不同的标签代表不同的意义&#xff0c;比如 am_pss&#xff0c;则代表内存回收&#xff08;整理&#xff09;。定义在源代码文件 &#xff1a; https://android.googlesource.com/platform/frameworks/base//master/servic…

字节5面挂,恶心到了。。。

字节五面 今天脉脉看到一篇帖子&#xff1a; 楼主是 tx 的前员工&#xff0c;在字节五面&#xff08;加轮&#xff09;被挂后&#xff0c;认定&#xff08;或许私下做了一些调查&#xff09;是字节 HR 向 tx 背调&#xff0c;然后被前同事捏造虚假信息&#xff0c;导致的面试失…

初识MVC

初识MVC 理论部分 今天第一次学MVC&#xff0c;拿到一个练手项目。现在来记录一下学习过程。 项目的背景就是个学生管理系统。我只做后端。 从大的来说MVC将应用程序分为三个主要组件&#xff08;部分&#xff09;&#xff1a; 模型&#xff08;Model&#xff09;是应用程序…

UE5像素流部署以及多实例部署(兼容ue4)

像素流部署请看我之前的文章就行&#xff0c;今天讲的是多实例部署 在这里可以配置多实例的数量 如果设置800端口 设置两个实例 那么就是800 801端口 我的个人显卡是4060TI,最多开三个

张大哥笔记:服务器有挖矿木马程序,该如何处理?

这篇文章发表于2021年&#xff0c;今天借这个平台再发布一下&#xff0c;希望对大家有所帮助&#xff01; 今天收到一个粉丝求助&#xff0c;说收到了阿里云官方短信通知提示有挖矿程序&#xff0c;要求立即整改&#xff0c;否则会关停服务器&#xff0c;以下是我和他的对话内…

238 基于matlab的水平轰炸弹道的求解

基于matlab的水平轰炸弹道的求解&#xff0c;列出轰炸弹道方程组并利用龙格库塔法解算弹道方程。设计中包含了二维弹道与三维弹道的计算&#xff0c;并都绘制了弹道运动轨迹&#xff0c;最终还将整个题目集中在一个图形用户界面&#xff08;GUI&#xff09;上。程序已调通&…

CTFHub-Web-SSRF

CTFHub-Web-SSRF-WP 一、内网访问 1.题目提示说访问127.0.0.1的flag.php&#xff0c;在URL后面添加路径没想到直接访问成功 二、伪协议读取文件 1.题目提示说访问Web目录下的flag.php&#xff0c;联想到Web目录一般存放于/var/www/html/里&#xff0c;去修改URL尝试进行访问…

Atlassian Jira 信息泄露漏洞(CVE-2019-3403) 排查思路

Atlassian Jira&#xff1a; 企业广泛使用的项目与事务跟踪工具&#xff0c;被广泛应用于缺陷跟踪、客户服务、需求收集、流程审批、任务跟踪、项目跟踪和敏捷管理等工作领域。 简述&#xff1a; 近日发现多个内网IP触发的Atlassian Jira 信息泄露漏洞的告警。 告警的检测规…