美文网首页
Node.js初探(四)

Node.js初探(四)

作者: 喑宝儿 | 来源:发表于2021-06-16 20:33 被阅读0次
1、初识express:

与http模块类似,对http进一步封装,专门用来创建web服务器

服务器:web网站服务器、API接口服务器

2、使用express创建最基本的服务器

(1)安装:npm i express@4.17.1

(2)创建简单的服务器以及请求

可以通过get和post进行请求处理

const express = require('express')

const app = express()
// 监听get请求
app.get('请求URL', function(req, res) {/* 处理函数 */})
// 监听post请求
app.post('请求URL', function(req, res) {/* 处理函数 */})

app.listen(3000, () => {
    console.log('express server running at http://127.0.0.1');
})

(3)send()函数

  • 可以在处理函数中调用 res.send(响应内容) 对当前请求进行响应

  • send()的响应内容可以是多种形式的

(4)获取URL中携带的查询参数:

  • req.query:默认情况下,内容为{ }

  • 请求URL:'/user'
    完整URL:http://127.0.0.1:3000/user?uname=zs&age=18
    req.query:
    {
      "name": "zs",
      "age": "18"
    }
    

(5)URL中的动态参数(可有多个动态参数):

  • req.params:默认状态下,内容为{ }

  • 请求URL:'/user/:uname/:age/:fav'
    完整URL:http://127.0.0.1:3000/user/zs/18/lily
    req.params:
    {
        "uname": "zs",
        "age": "18",
        "fav": "lily"
    }
    
3、使用express托管静态资源
  • app.use(express.static(要托管的资源的路径))
    app.use(express.static('./shopping'))
    
  • 托管多个静态资源目录:多次调用app.use(express.static(资源路径))

  • 访问静态资源时,express.static()会根据目录的添加顺序查找所需的文件

4、挂载路径前缀(在访问静态资源时,必须加上路径的前缀才能访问得到)
  • app.use(路径前缀, express.static(要托管的资源的路径))
    app.use('/public', express.static('./shopping'))
    
5、路由:映射关系

(1)express中的路由

  • 路由:客户端的请求与服务器处理函数之间的映射关系(包括请求方式、请求URL、处理函数)

(2)路由的匹配过程

  • 按照定义的先后顺序进行匹配

  • 请求类型和请求URL地址需要同时匹配成功,才会调用对应的处理函数

6、挂载路由
// app express对象
app.get('/', function(req, res) { res.send('111') })
app.post('/', function(req, res) { res.send('222') })

一般路由不建议直接挂载

7、模块化路由
/** router.js */
// 1、导入express
const express = require('express')
// 2、创建路由对象
const router = express.Router()
// 3、挂载具体的路由
router.get('/user/list', (req, res) => {
    res.send('get user list')
})
router.post('/user/add', (req, res) => {
    res.send('add user list')
})
// 4、向外导出路由对象
module.exports = router
/** 使用test.js */
const express = require('express')
const app = express()
// 1、导入路由模块
const router = require('./03.router')
// 2、注册路由模块
app.use(router)
app.listen(80, () => {
    console.log('http://127.0.0.1');
})

app.use():专门用来注册中间件的

app.use(访问前缀, router):也可以为路由模块挂载访问前缀,在访问路由时都需要加上

8、中间件:用户请求到路由匹配中间的过程(对请求进行预处理)

(1)express中间件的格式

本质是一个函数,在函数的形参列表中,必须包含next参数,next必须是最后一个参数

(2)next函数的作用

实现多个中间件连续调用,表示把流转关系转交给下一个中间件或路由

(3)定义中间件函数

const mw = function(req, res, next) {
    console.log('这是一个中间件函数')
  // 将流转关系,转交给下一个中间件函数
    next()
}

(4)注册中间件

全局生效的中间件:app.use(中间件函数)

// 将mw注册为全局生效的中间件,中间件都要在路由的前面进行定义,发送请求先进入中间件
app.use(mw)

中间件的作用:

多个中间件之间,共享一根req和res,基于这样的特性,可以在上游的中间件中,统一为req或者res对象添加自定义的属性或方法,供下游的中间件或路由进行使用

app.use((req, res, next) => {
  req.startTime = Date.now()
  next()
})

app.get('/', (req, res) => {
  res.send('Home' + req.startTime)
})

app.get('/user', (req, res) => {
  res.send('User' + req.startTime)
})

定义多个全局中间件:

可以使用app.use()连续定义多个全局中间件,客户端请求到达服务器之后,会按照中间定义的先后顺序依次进行调用

app.use((req, res, next) => {
  console.log('第一个')
  next()
})

app.use((req, res, next) => {
  console.log('第二个')
  next()
})

局部生效的中间件:不使用app.use()定义的中间件

// 只会在/路由中才会打印'局部中间件',因为只给/路由注册
const mw = function(req, res, next) {
    console.log('局部中间件')
    next()
}

app.get('/', mw, (req, res) => {
  res.send('Home')
})

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

定义多个局部中间件:

// 下面两个是等价的
app.get('/', mw1, mw2, (req, res) => { res.send('Page') })
app.get('/', (mw1, mw2), (req, res) => { res.send('Page') })
9、中间件的注意事项

(1)一定要在路由之前注册中间件

(2)客户端发过来的请求,可以连续调用多跟中间件进行处理

(3)执行完中间件的业务代码之后,不要忘记调用next()函数

(4)为了防止代码逻辑混乱,调用next()函数之后不要再写额外的代码

(5)连续调用多个中间件时,多个中间件之间,共享req和res对象

10、中间件的分类

(1)应用级别:app.use()/app.get()/app.post(),直接绑定到app实例上的中间件

(2)路由级别:绑定到express.Router()实例上的中间件(和应用级别用法相同)

(3)错误级别:

捕获整个项目中发生的异常错误,防止项目异常崩溃的问题

错误级别的中间件一定要写在路由之后

格式:处理函数中,必须有4个形参,顺序从前到后,分别是(err, req, res, next)

const express = require('express')
const app = express()

// 1、定义路由
app.get('/', (req, res) => {
    throw new Error('服务器内部发生了错误!')
    res.send('Home page')
})

// 2、定义错误级别的中间件
app.use((err, req, res, next) => {  // 错误级别中间件
    console.log('Error:' + err.message);  // 1、在服务端打印错误信息
    res.send('Error:' + err.message)  // 2、向客户端返回错误信息
})

app.listen(80, () => {
    console.log('http://127.0.0.1');
})
11、Express内置的中间件

(1)express.static:静态托管资源

(2)express.json:解析JSON格式的请求体数据

(3)express.urlencoded:解析URL-encoded格式的请求体数据

// 解析JSON
app.use(express.json())

// 解析urlencoded
app.use(express.urlencoded({ extended: false }))
12、第三方中间件body-parser(解析请求体数据)

(1)安装:npm i body-parser

(2)使用require导入文件

(3)调用app.use()注册并使用中间件

const express = require('express')
const app = express()

const parser = require('body-parser')
app.use(parser.urlencoded({ extended: false }))

app.post('/', (req, res) => {
    console.log(req.body);
    res.send('ok')
})

app.listen(80, () => {
    console.log('http://127.0.0.1');
})

内置请求体解析中间件就是对body-parser中间件的封装

13、自定义中间件:模拟express.urlencoded类似功能

(1)定义中间件

(2)监听req的data操作:查看是否有数据被提交

(3)监听req的end事件:数据已经发送完毕,服务端已经接收到了数据

(4)使用querystring模块解析请求体数据:

(5)将解析出来的数据对象挂载为req.body

(6)将自定义的中间件封装为模块

完整文件

const express = require('express')
const app = express()

const bodyParse = require('./bodyParse')

app.use(bodyParse)

app.post('/user', (req, res) => {
    res.send(req.body)
})

app.listen(80, () => {
    console.log('http://127.0.0.1');
})

可以将功能单独封装(// 步骤(6)),然后再注册路由中间件(bodyParse.js)

const qs = require('querystring')

// 步骤(1)
const bodyPaser = (req, res, next) => {
    var str = ''
    // 步骤(2)
    req.on('data', chunk => {
        str += chunk
    })
    // 步骤(3)
    req.on('end', () => {
        // 步骤(4)(5)
        req.body = qs.parse(str)
        next()
    })
}

module.exports = bodyPaser

相关文章

  • Node.js初探(四)

    1、初识express: 与http模块类似,对http进一步封装,专门用来创建web服务器 服务器:web网站服...

  • webpack4 模块打包工具1

    第一章 webpack初探 环境安装 node.js[https://nodejs.org/en/]image.p...

  • node.js初探

    创建第一个node.js应用 node server.js接下来,打开浏览器访问 http://127.0.0.1...

  • react-native初探

    react-native初探 一 、必备软安装   两个基本软件 :node.js和python2  中文网上使用...

  • Nacos进阶(一)-- 集群模式部署Nacos

    关于Nacos已经展开了四篇入门文章: 初探Nacos(一)-- 单机模式启动 初探Nacos(二)-- Spri...

  • Node.js初探(二)

    1、模块化 (1)遵守固定的规则,把一个大文件拆成独立并相互依赖的多个小模块 (2)好处:复用性、可维护性、可实现...

  • Node.js初探(三)

    1、包 第三方模块,第三方免费提供下载,包是基于内置模块封装出来的 2、包的操作 https://www.npmj...

  • Nodejs.2

    参考内容:Node.js EventEmitter 四、Node.js EventEmitter Node.js所...

  • 卷一 初探身世 阴谋四起

    卷一 初探身世 阴谋四起

  • ^。^_________初探Node.js 安装篇_______

    Node.js,What is? Node.js 就是运行在服务器端的Javascript。Node.js 是基于...

网友评论

      本文标题:Node.js初探(四)

      本文链接:https://www.haomeiwen.com/subject/smvfyltx.html