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

一、Express

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

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

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

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

Express 框架核心特性:

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

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

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

Express适合做什么

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

二、Express项目构建

csharp 复制代码
npm init -y
csharp 复制代码
npm install express --save
csharp 复制代码
npx express-generator

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

这个生成的项目通常包括以下部分:

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

三、express框架的基本使用

javascript 复制代码
// 引入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 头部等属性。常见属性有:

javascript 复制代码
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 响应数据。常见属性有:

javascript 复制代码
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

javascript 复制代码
{
  "users": [
    {
      "id": 1,
      "username": "Monica",
      "age": "22"
    },
    {
      "id": 2,
      "username": "Alen",
      "age": "26"
    }
  ],
  "video": []
}
javascript 复制代码
// 引入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去管理接口

解决回调地狱问题:

javascript 复制代码
// 引入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请求数据

javascript 复制代码
// 引入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文件

拿到提交的表单值:

javascript 复制代码
// 引入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');
})

文件写入:

javascript 复制代码
// 引入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

javascript 复制代码
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

javascript 复制代码
// 引入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');
})

七、修改用户信息

javascript 复制代码
// 引入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还挺有意思的

相关推荐
Ztiddler6 小时前
【npm设置代理-解决npm网络连接error network失败问题】
前端·后端·npm·node.js·vue
前端青山7 小时前
webpack进阶(一)
前端·javascript·webpack·前端框架·node.js
老攀呀9 小时前
安装多个nodejs版本(nvm)
node.js
佚名程序员9 小时前
【Node.js】全面解析 Node.js 安全最佳实践:保护您的应用
安全·node.js
zxg_神说要有光21 小时前
快速入门 AI:调用 AI 接口生成 React 组件
前端·javascript·node.js
佚名程序员21 小时前
【Node.js】深入理解 V8 JavaScript 引擎
前端·javascript·node.js
赵闪闪16821 小时前
Node.js 安装与开发环境配置全指南
node.js
前端与小赵21 小时前
什么是Webpack,有什么特点
前端·webpack·node.js
生椰拿铁You1 天前
03 —— Webpack 自动生成 html 文件
前端·webpack·node.js
赵闪闪1681 天前
Node.js 安装与环境配置详解:从入门到实战
node.js·编辑器·vim