Node.js-- Express

0.学习目标:

◆能够使用express.static() 快速托管静态资源
◆能够使用express路由精简项目结构
◆能够使用常见的express中间件
◆能够使用express创建API接口
◆能够在express中启用cors跨域资源共享

1.理解express

  1. http 模块也可以创建Web 服务器,express是基于 http 内置模块【用起来复杂,开发效率低】进一步封装的,可以极大提高开发效率,快速方便创建 服务器【Web服务器 以及 API接口服务器】
  2. 基本使用:
    1. 获取URL中携带的查询参数 req.query
    2. 获取URL的动态参数 req.params
    3. 托管静态资源,创建静态资源服务器: express.use(express.static('文件目录')),其中静态文件目录不会出现在URL中,托管多个,多次访问,
const express = require('express')
const app = express()
   // clock为同级别根目录,app.use 注册路由模块
app.use(express.static('./clock'))

app.listen(80, () => {
    console.log('express server running at local');
})
5. 挂载路径前缀: express.use('/文件路径',express.static('public'),访问的时候需要加前缀

2.基本使用

// 创建express模板
const express = require('express')
    // 创建web服务器
const app = express()
    // 设置监听端口
app.listen(80, () => {
        console.log('express server running at local');
    })
    // 挂载路由,向客户端响应对象
app.get('/user', (req, res) => {
    // 1. send响应JSON对象
    res.send({ name: 'gyp', age: '20', gender: 'woman' })
})

app.post('/user', (req, res) => {
    //2. send响应文本字符串
    res.send('请求成功')
})
// req.query 获取到客户端发送过来的 查询参数
app.get('/', (req, res) => {
    console.log(req.query);
    res.send(req.query)
})
// req.params是动态匹配参数
app.get('/user/ :ids/:name', (req, res) => {
    console.log(req.params);
    res.send(req.params)
})

3.路由

  1. 客户端请求与服务器处理函数之间的映射(一 一对应)关系,
  2. 组成:请求的类型,请求的URL地址,处理函数,
app.METHOD(PATH,HANDLER)
  1. 匹配过程:请求到达服务器,先经过路由经过先后顺序的匹配,请求类型以及请求URL地址同时匹配成功后,express将该请求转交给相应函数

  2. 为了方便对路由进行模块化的管理,Express不建议将路由直接挂载到app上,而是推荐将路由抽离为单独的模块。
    5.app.use( ) 作用:注册全局中间件(static,router)

     1. 向外托管静态函数 
    
app.use(express.static('./clock'))
      2. 注册路由模块
app.use(router)
  1. 挂载统一前缀 ,类似静态资源托管,在app.use内

4.Express中间件

1. 调用流程:

在服务器内,(可以连续调用多个中间件进行预处理)处理【请求】保证其达到标准(可以作为路由形式返回给客户端),一般包含输入和输出

2. 格式:

本质是function 处理函数, 与路由处理函数区别:中间件处理函数包含第三个形参是 next ,路由处理函数仅有req,res

3. next 函数作用:

多个中间件连续调用的关键,表示吧流转关系转交给下一个中间件或路由

4. 定义中间件函数

const express = require('express')

// 定义一个最简单的中间件函数
const mw = function(req, res, next) {
        console.log('这是一个最简单的中间件函数');
        // 调用Next函数, 表示把流转关系转交给下一个中间件或路由
        next()
    }
    // 1.最简单的服务器创建
const app = express()
app.listen(80, () => {
    console.log('80端口响应成功');
})

5. 全局生效的中间件:

客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间价。通过调用app.use(中间件函数),即可定义一个全局生效的中间价

    // 1. 定义一个最简单的中间件函数
    const mw = function(req, res, next) {
        console.log('这是一个最简单的中间件函数');
        // 调用Next函数, 表示把流转关系转交给下一个中间件或路由
        next()
    }
    // 将 mw 注册为全局生效的中间件,可以交给后面的路由
    app.use(mw)

// 2. 简化全局中间件
app.use(function(req, res, next) {
    console.log('一个简单函数');
    next()
})

6. 中间件作用:

多个中间件之间,共享一份 req和 res 。可以在上游的中间件统一为req和res添加自定义的属性和方法,供下游的中间件或路由使用

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

app.use(function(req, res, next) {
    console.log('调用了第1个中间件');
    next()
})

app.use(function(req, res, next) {
    console.log('调用了第2个中间件');
    next()
})

app.use('/user', function(req, res) {
    res.send('Home page.')
})

// 创建了简单服务器
app.listen(80, () => {
    console.log('800端口启动');
})

7. 局部生效的中间件:

不使用app.use( ) 定义的中间件

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

const mw1 = function(req, res, next) {
        console.log('我是中间件函数');
        next()
    }
    // 先交给中间件处理,再交给后面路由处理函数
app.use('/', mw1, function(req, res) {
    res.send('Home page')
})

app.get('/user', function(req, res) {
    res.send('Use page')
})

app.listen(80, () => {
    console.log('局部生效的端口监听中');
})

8. 定义多个局部中间件,通过如下两种等价方式

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 1. 定义中间件函数
const mw1 = (req, res, next) => {
  console.log('调用了第一个局部生效的中间件')
  next()
}

const mw2 = (req, res, next) => {
  console.log('调用了第二个局部生效的中间件')
  next()
}

// 2. 创建路由
//app.get('/', mw1, mw2, (req, res) => { 与下面等价  
app.get('/', [mw1, mw2], (req, res) => {
  res.send('Home page.')
})
app.get('/user', (req, res) => {
  res.send('User page.')
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

9. 注意事项:

![1. 中间件只能在路由之前注册
2. 客户端发送过来的请求可以连续调用多个中间件处理
3. 执行完中间件的业务代码后,不要忘记调用next( )函数
4.](https://img-blog.csdnimg.cn/2d19016e6f9d49a1bad011ea71b22f97.png)

10. 中间件分类【按用法分】:

1. 应用级别 app.use; get; post

在这里插入图片描述

2. 路由级别 express.Router

在这里插入图片描述

3. 错误级别中间件:必须放到所有路由之后 4个参数

![在这里插入图片描述](https://img-blog.csdnimg.cn/3795c8a8e51a44abb8b2faca6ad7f2ae.png]

7. Express 内置 express.json(); express.urlencoded({ extended: false })

在这里插入图片描述

// 通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据
app.use(express.json())
// 通过 express.urlencoded() 这个中间件,来解析 表单中的 url-encoded 格式的数据
app.use(express.urlencoded({ extended: false }))
// const { json } = require('express');
const express = require('express')
const app = express()

// 1. express.json解析表单中json格式的数据到服务器
app.use(express.json())
    // 2. express.urlencoded 解析表单中的数据和url-encoded格式的数据
app.use(express.urlencoded({ extended: false }))

app.use('/user', (req, res) => {
    // 1.服务器使用req.body 接收客户端发送来的  请求体  数据
    // 默认情况 ,不配置解析表单中间件,req,body为undefine
    console.log(req.body);
    res.send('ok')
})

app.post('/book', (req, res) => {
    // 2.服务器端使用req.body 获取JSON格式的表单数据和url-encoded 格式的数据
    console.log(req.body);
    res.send('oook')
})

app.listen(80, () => {
    console.log('80端口监听中');
})
5. 第三方中间件 body-parser

在这里插入图片描述

// 1. 导入解析表单数据的中间件 body-parser
const parser = require('body-parser')
// 2. 使用 app.use() 注册中间件
app.use(parser.urlencoded({ extended: false }))
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 注意:除了错误级别的中间件,其他的中间件,必须在路由之前进行配置
// 通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据
app.use(express.json())
// 通过 express.urlencoded() 这个中间件,来解析 表单中的 url-encoded 格式的数据,但无法解析中文数据
app.use(express.urlencoded({ extended: false }))

app.post('/user', (req, res) => {
  // 在服务器,可以使用 req.body 这个属性,来接收客户端发送过来的请求体数据
  // 默认情况下,如果不配置解析表单数据的中间件,则 req.body 默认等于 undefined
  console.log(req.body)
  res.send('ok')
})

app.post('/book', (req, res) => {
  // 在服务器端,可以通过 req,body 来获取 JSON 格式的表单数据和 url-encoded 格式的数据
  console.log(req.body)
  res.send('ok')
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})
  1. 自定义中间件
    自己手动模拟一个类似于express.urlencoded这样的中间件,来解析POST提交到服务器的表单数据。
    实现步骤:
    ①定义中间件
app.use((req, res, next) => {
  // 定义中间件具体的业务逻辑
  })

②监听req的data事件
在这里插入图片描述
③监听req的end事件
在这里插入图片描述
④使用querystring模块解析请求体数据

const express = require('express')
const app = express()
// 内置querystring模块,专门处理查询字符串,提供parse函数吧字符串解析为对象
const qs = require('querystring')


app.use('/user', (req, res) => {
    let str = ''
    req.on('data', (chunk) => {
        str += chunk
    })

    req.on('end', () => {
        // 将字符串解析为对象
        const body = qs.parse(str)
        console.log(body);

    })
    res.send('ok')
})


app.listen(80, () => {
    console.log('在监听啦!');
})

⑤将解析出来的数据对象挂载为req.body
在这里插入图片描述
在这里插入图片描述

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
// 导入 Node.js 内置的 querystring 模块
const qs = require('querystring')

// 这是解析表单数据的中间件
app.use((req, res, next) => {
  // 定义中间件具体的业务逻辑
  // 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
  let str = ''
  // 2. 监听 req 的 data 事件
  req.on('data', (chunk) => {
    str += chunk
  })
  // 3. 监听 req 的 end 事件
  req.on('end', () => {
    // 在 str 中存放的是完整的请求体数据
    // console.log(str)
    // TODO: 把字符串格式的请求体数据,解析成对象格式
    const body = qs.parse(str)
    req.body = body
    next()
  })
})

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

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})


⑥将自定义中间件封装为模块
封装函数

// 导入querystring模块
const qs = require('querystring')
    // 封装 中间件 函数
const bodyParser = (req, res, next) => {
        let str = ''
    // 拼接字符串
        req.on('data', (chunk) => {
            str += chunk
        })
        // 调用parse函数将字符串转化为对象
        req.on('end', () => {
                const body = qs.parse(str)
                req.body = body
                next()
            }
        }

        // 向外导出解析请求体数据的中间件函数
        module.exports = bodyParser

调用函数

// 导入自己封装的中间件模块
const customBodyParser = require('./49.4.custom-body-parser')
    // 将自定义的中间件函数,注册为全局可用的中间件
app.use(customBodyParser)

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

5.Express写接口

(以下代码均省略创建基本服务器:导入模块,创建服务器以及【需要实现的路由部分】设置监听端口)

1. 创建基本API 路由模块

在这里插入图片描述

2. 编写GET 接口

const express = require('express')
const router = express.Router()

// 挂载对应路由
router.get('/get', (req, res) => {
    // 1.获取到客户端通过查询字符串发送到服务器的数据
    const query = req.query
        // 2.调用res.send() 响应数据给客户端
    res.send({
        status: 0, //0表示处理成功
        msg: 'GET请求成功!', //状态描述
        data: query //响应给客户端的数据
    })
})
module.exports = router

调用GET接口

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

// 导入路由模块
const router = require('./49.5.apiRouter')
    // 把路由模块注册到app上
app.use('/api', router)

app.listen(80, () => {
    console.log('80端口监听成功');
})

3. 编写POST接口

router.post('/post', (req, res) => {
    const body = req.body
    res.send({
        status: 0,
        msg: 'POST 请求成功!',
        data: body
    })
})

4 .编写接口 - 基于cors解决接口跨域问题

1.接口的跨域问题:

刚才编写的GET和POST请求,存在一个很严重的问题:不支持跨域请求。
解决接口跨域问题的方案主要有两种:
1.CORS(主流的方案,推荐使用)
2.JSONP(有缺陷的解决方案:只支持GET请求,很少使用)
使用cors中间件解决跨域问题

// 务必在路由之前使用cors模板,解决跨域问题
const cors = require('cors')
app.use(cors())
2.跨域——三个响应头(CORS:跨域资源共享)

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

1.CORS响应头部- Access-Control-Allow-Origin

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

2.CORS响应头部- Access-Control-Allow-Headers

在这里插入图片描述

3.CORS响应头部- Access-Control-Allow-Methods

在这里插入图片描述

3.跨域——请求的分类
1. 简单请求

在这里插入图片描述

2.预检请求

在这里插入图片描述
谷歌浏览器无法演示预检请求,建议用火狐

两者区别

在这里插入图片描述

3. 跨域——编写 jsonp 接口
  1. 概念: 概念:浏览器端通过
// 3. 必须在配置 cors 中间件之前配置JSONP接口
app.get('/api/jsonp', (req, res) => {
    // 定义JSONP接口具体实现过程
    // 1.得到函数名称
    const funcName = req.query.callback
        // 2.定义发送到客户端1的对象
    const data = { name: 'GYP', age: 20 }
        // 3.拼接函数的调用 cb(),转为字符串
    const scriptStr = '${funcName}(${JSON.stringify(data)})'
        // 4.拼接字符好惨响应给客户端
    res.send(scriptStr)
})

// 2. cors模板,解决跨域问题
const cors = require('cors')
app.use(cors())

.在网页中使用jQuery发起JSONP请求

     // 3. 测试JSONP接口
            $('#btnJSONP').on('click', function() {
                $.ajax({
                    type: 'GET',
                    url: 'http://127.0.0.1/api/jsonp',
                    dataType: 'jsonp',
                    success: function(res) {
                        console.log(res);
                    }
                })
            })
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值