08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎.

Express框架 

目标

  1.  能够使用Express创建web服务器
  2.  能够使用Express处理请求参数
  3.  能够使用Express处理静态资源
  4.  能够使用中间件处理请求
  5.  能够在Express中集成art-template模板引擎
  6.  Express框架简介及初体验
  7.  Express框架请求处理
  8.  express-art-template模板引擎
  9.  Express中间件

 

1. Express框架简介及初体验

1.1 Express框架是什么?

1)Express是一个基于Node平台的web应用开发框架,它提供了一系列的强大特性,帮助你创建各种Web网站应用。使用原生JS代码写起来比较复杂,比较底层的;比如实现路由功能,需要对请求地址进行解析,还要进行各种判断,代码乱,不易阅读;再比如,实现静态资源访问功能,还要使用文件读取模块,对文件内容读取,还要设计响应内容类型,但实际和网站本身的业务逻辑没有关系;还有,接收post请求参数的代码,需要对请求对象添加事件,手动拼接请求参数,对请求参数的格式进行转化,都是复杂的,并且还是和和业务逻辑没有关系;原生JS实现网站应用比较困难,express就出现了

2)这个是nodejs的第三方模块-使用 npm install express 命令进行下载。企业中创建web应用的标准

1.2 Express框架特性

  • 提供了方便简洁的路由定义方式:router第三方模块 ,其实就是从express框架中抽取出来的
  • 对获取HTTP请求参数进行了简化处理:不用再转换格式,直接拿到对象类型
  • 模板引擎 支持程度高,方便渲染动态HTML页面;
  • 提供了中间件(对请求的拦截)机制有效控制HTTP请求
  • 拥有大量第三方中间件 对功能进行扩展:非常少的代码,做同样的事情

1.3 原生Node.js与Express框架对比 之 路由

app.on('request', (req, res) => {

     // 获取客户端的请求路径

     let { pathname } = url.parse(req.url);

     // 对请求路径进行判断 不同的路径地址响应不同的内容

     if (pathname == '/' || pathname == 'index') {

        res.end('欢迎来到首页');

     } else if (pathname == '/list') {

        res.end('欢迎来到列表页');

     } else if (pathname == '/about') {

        res.end('欢迎来到关于我们页面')

     } else {

        res.end('抱歉, 您访问的页面出游了');

     }

 });

// 当客户端以get方式访问/

 app.get('/', (req, res) => {

     // 对客户端做出响应

     res.send('Hello Express');

 });

 // 当客户端以post方式访问/add路由时

 app.post('/add', (req, res) => {

    res.send('使用post方式请求了/add路由');

 });

 

1.4 原生Node.js与Express框架对比 之 参数

app.on('request', (req, res) => {

    // 获取GET参数

    let { query} = url.parse(req.url, true);

    // 获取POST参数

    let postData = '';

    req.on('data', (chunk) => {

        postData += chunk;

    });

    req.on('end', () => {

        console.log(querystring.parse(postData)

    }));

 });

app.get('/', (req, res) => {

    // 获取GET参数req.query

    console.log(req.query);

 });

 app.post('/', (req, res) => {

    // 获取POST参数 req.body

    console.log(req.body);

 })

 

1.5 Express初体验

使用Express框架 创建web服务器及其简单,调用express模块 返回的函数即可

命令行下载 npm install express

//1, 引入Express框架,返回值是一个方法,通过调用这个方法,就可以创建网站服务器,就不用HTTP模块和调用createserver()方法

 const express = require('express');

//2, 使用框架创建web服务器 + 监听端口 = 向外提供服务

 const app = express();

 

 // 4, 当客户端以get方式访问/路由时, 服务器要创建路由来响应客户端的请求;如何创建路由,和第三方模块 router是一样的 app.get(‘默认访问地址/’,请求处理函数,两个参数分别为 请求对象和 响应对象) 用来接受 get 请求

 app.get('/', (req, res) => {

// 不再是res.end(), 对客户端做出响应 send()方法会根据内容的类型自动设置请求头

// send() 内部回检测响应内容的类型;会自动设置HTTP状态码;会帮我们自动设置响应的内容类型以及 编码

    res.send('Hello Express'); //

Hello Express

{say: 'hello'}

 });

 

//在定义一个路由,当访问 / list 的时候,响应一个其他内容;send 内部 还可以传递Json 对象

app.get('/list', (req, res) => {

           res.send({name: '', age: 20})

})

//3, 程序监听3000端口

 app.listen(3000);

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第1张图片

 

2. 中间件

2.1 什么是中间件

1) 中间件就是 一堆方法可以 接收客户端发来的请求可以对请求做出响应也可以将请求继续交给下一个中间件继续处理。专门接受请求处理请求的

下图:中间件处理请求的过程:

图两边是当客户端浏览器, 向中间的服务器发送请求

当浏览器发送请求,服务器可以使用中间件 接受这个请求进行处理,直接对客户端做出响应,或者交给下一个中间件继续处理,有下一个 中间件对客户端浏览器做出相应;

中间件好处:可以对复杂的请求处理逻辑,进行分开处理,也可以再请求到到指定路由之前做一些验证:比如查看用户是不是登录,如果登录,在向下继续执行

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第2张图片

2) 中间件主要由两部分构成,中间件方法以及请求处理函数中间件方法 由Express框架提供,负责拦截请求请求处理函数 由开发人员提供,负责处理请求

app.get('请求路径', '处理函数')   // 接收并处理get请求

app.post('请求路径', '处理函数')  // 接收并处理post请求

3) 可以针对同一个请求设置 多个中间件对同一个请求进行多次处理

默认情况下,请求从上到下依次匹配中间件,一旦匹配成功,终止匹配

可以调用第三个参数next()方法将请求的控制权交给下一个中间件,直到遇到结束请求的中间件

app.get('/request', (req, res, next) => {

     req.name = "zhangsan";

     next();

 });

app.get('/request', (req, res) => {

     res.send(req.name);

 });

 

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第3张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第4张图片  

2.2 app.use中间件用法

-   app.use 匹配所有的请求方式可以直接传入请求处理函数代表接收所有的请求,只要客户端发来请求,就可以匹配到当前中间件

中间件是有顺序的,所以,中间件必须定义在其他前边;否则其他中间件匹配到了这个请求,有没有将权力交给下一个中间件,也是匹配不到这个中间件的

app.use((req, res, next) => { console.log(req.url);  next(); });

  • app.use 第一个参数 也可以传入请求地址,代表不论什么请求方式,只要是这个请求地址就接收这个请求。

app.use('/admin', (req, res, next) => { console.log(req.url); next(); });

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第5张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第6张图片

2.3 中间件应用

1. 路由保护,客户端在访问 需要登录的页面时可以先使用中间件判断用户登录状态,用户如果未登录,则拦截请求,直接响应, 禁止用户进入需要登录的页面

// 定义一个路由:要访问必须要先登录可以的

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第7张图片

2. 网站维护公告在所有路由的最上面定义接收所有请求的中间件,直接为客户端做出响应,网站正在维护中。

// 网站公告,比如在凌晨 6:00 -12:00 要维护,不想要用户访问这个网站,要定义在所有的路由的前边,没有调用 next(), 请求到这里就截止了

 app.use((req, res, next) => {

          res.send('当前网站正在维护,请在其他时间段访问...')

})

3. 自定义404页面,用户访问路径不存在时,同时用户访问的页面不存在,当所有用户访问的上边所有的路由不存在,才会响应给用户,所以定义在所有路由最后边,不会调用next();status404)更改状态码,为客户端响应404状态码以及提示信息

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第8张图片

2.4 错误处理中间件

在程序执行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败数据库连接失败,错误处理中间件是一个集中处理错误的地方。

想要出错以后,还能继续运行,需要捕获错误,加入错误处理;程序错误分为两种:

  1. 应用逻辑错误:=bug 开发阶段解决
  2. 读取硬盘文件/数据库连接错误:无法开发阶段预料到,在运行过程中,需要被捕获和妥善处理;

如何处理错误呢?在每一个会出错的地方进行判断,但是代码太多!所以提供了错误处理中间件;

只能捕获到 同步代码错误!!!异步需要手动触发调用next(0方法 当异步程序出现错误时,调用next()方法,并且将错误信息通过参数的形式传递给next()方法,即可触发错误处理中间件

有四个参数,发生错误,自动执行错误处理中间件

app.use((err, req, res, next) => {

     res.status(500).send('服务器发生未知错误');

 })

如果文件读取错误,系统会把错误信息通过参数传给我们,我们对错误对象进行判断,如果它真的时错误对象,不是null,就调用next()方法,传给他,他就会触发错误处理中间件了

app.get("/", (req, res, next) => {

     fs.readFile("/file-does-not-exist", (err, data) => {

         if (err) {

            next(err);

         }

     });

});

//05js 错误处理中间件

// 引入express框架 + 文件读取模块

const express = require('express');

const fs = require('fs');

// 创建网站服务器

const app = express();

// 普通的路由中间件

app.get('/index', (req, res, next) => {

       // throw new Error('程序发生了未知错误') 抛出错误 ,不报错往下执行

       fs.readFile('./01.js', 'utf8', (err, result) => {

             if (err != null) {

                    next(err) // 传参数,代表触发中间件,不传参数,代表控制权交给下一个

             }else {

                    res.send(result)

             }

       })

       // res.send('程序正常执行')

})

// 错误处理中间

app.use((err, req, res, next) => {

       res.status(500).send(err.message);

})

// 监听端口 

app.listen(3000);

console.log('网站服务器启动成功');

2.5 捕获错误

node.js异步API的错误信息都是通过 回调函数 获取的支持Promise对象的异步API 发生错误可以通过catch方法捕获 异步函数执行如果发生错误要如何捕获错误呢

try catch 可以捕获 异步函数以及其他同步代码 在执行过程中发生的错误,但是 不能捕获其他类型的API发生的错误

app.get("/", async (req, res, next) => {

     // 如果程序没有错误,跳到trycatch外;如果程序有错误,会执行catch里边的代码,里边的参数就是错误信息,可以调用next方法,手动触发错误处理中间件;try()里边的代码,是从数据块中查询数据,如果查询失败,就跳转catch,执行并将错误信息传给错误处理中间件;

     try {

         await User.find({ name: '张三'})

     }catch(ex) {

         next(ex); // 调用next() 触发错误处理中间件

     } });

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第9张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第10张图片

命令行已经不报错了,程序就可以继续执行;增加了我们程序的健壮性

 

3. Express请求处理

3.1 构建模块化路由

虽然已经可以通过 app.get(), app.post()方法创建路由了,但是在一般情况下,路由的数量是非常多的,如果将所有的放在同一文件中,非常可怕,所以express提供了模块化,进行分类,不同的类型路由放在不同的模块中,方便管理。

例如:博客网站:用户看的文章列表,详情页面;管理员看的文章发布,管理页面等。设置不同的路由进行分别管理

const express = require('express') // 引入框架,返回express方法,直接调用或者使用他下边的其他方法;比如 express.Router用来创建路由

const home = express.Router();// 创建路由对象

app.use('/home', home); // 将路由和请求路径进行匹配;当客户端访问什么请求路径时/home'才能使用当前路由来处理,用app.use()方法来匹配 home;代码中并没有请求处理函数,请求来了以后,在哪里处理呢?具体请求处理再二级路由中完成

home.get('/index', () => { // home路由下的get()方法继续创建路由,访问:/home/index 二级路由

         res.send('欢迎来到博客展示页面'); //  /home/index

 });

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第11张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第12张图片

3.2 构建模块化路由

// home.js

// admin,js

// app.js

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第13张图片

3.3 GET参数的获取

Express框架中使用 req.query 即可获取 GET参数 query 属性下存的就是 get请求参数,不在需要引入url 模块,通过对请求地址进行解析来获取get 请求参数了;框架内部会将GET参数 转换为 对象并返回

// 接收地址栏中问号后面的参数,客户端访问时加了请求参数 name=zhangsan&age=30

// 例如:  http://localhost:3000/?name=zhangsan&age=30

 app.get('/', (req, res) => {

    console.log(req.query); // 直接通过 req.query 就可以拿到?号后的请求参数了,并且已经解析成对象类型{"name": "zhangsan", "age": "30"} });

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第14张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第15张图片

 

3.4 POST参数的获取

Express中接收 post请求参数 需要借助第三方包 body-parser。Npm i body-parser下载

const bodyParser = require('body-parser'); // 引入body-parser模块

app.use(bodyParser.urlencoded({ extended: false }));// 配置body-parser模块;使用app.use()这个中间件拦截所有请求,调用'body-parser'模块下边的 urlencoded() 方法,对请求进行处理,方法内部会检测当前请求中是不是包含请求参数,如果包含,就接受并转换为对象类型;然后在为req这个请求添加一个属性,属性的名字叫body;并且将参数作为值赋值给 req.body属性,最后调用next()将请求控制权交给下一个中间件

app.post('/add', (req, res) => { // 接收请求

    console.log(req.body); // 接收post请求参数

 })

10.js 如何获取post请求参数

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第16张图片 

 

 

如何发送 post 请求,通过表单就可以:post.html

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第17张图片

点击提交后,就提交到 /add这个路由地址去了:

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第18张图片

11.js app.use方法

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第19张图片

3.5 Express 路由参数

传递和接受 get 请求参数,还有另一种方式; 路由参数;可以让请求地址看起来美观,路由代码容易阅读;更容易看出传了那些参数;:id 是一个占位符,请求当前路由,要传递一个id 作为参数,不是实际的参数

app.get('/find/:id', (req, res) => {

console.log(req.params); // {id: 123} req.params 获取参数

 });

localhost:3000/find/123  // 请求参数/id = 123

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第20张图片08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第21张图片

3.6 静态资源的处理

通过Express内置的 express.static可以方便地托管静态文件,例如imgCSSJavaScript 文件等。

app.use(express.static('public')); express.static(‘参数:静态资源存放的目录’);调用传给app.use()中间件,拦截所有请求,将请求交给express.static()这个方法处理,并且将静态资源目录告诉express.static()方法;方法内部判断客户端发来的请求,如果是静态资源请求,直接响应给客户端,终止请求;如果不是再方法内部调用next()将请求控制权交给下一个中间件开启静态资源访问功能后,就可以public 目录下面的文件就可以通过以下方式访问了

  • http://localhost:3000/images/kitten.jpg  
  • http://localhost:3000/css/style.css  
  • http://localhost:3000/js/app.js
  • http://localhost:3000/images/bg.png  
  • http://localhost:3000/hello.html  

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第22张图片

访问:http://localhost:3000/static/images/1.jpg

 

4. express-art-template模板引擎

4.1 模板引擎

  1. 为了使 art-template模板引擎 能够更好的和 Express框架配合,模板引擎官方在原art-template模板引擎的基础上封装了express-art-template
  2. 使用 npm install art-template express-art-template 命令进行安装。

// 告诉express 框架,使用的模板引擎是什么? 当渲染后缀为art的模板时 使用express-art-template

 app.engine('art', require('express-art-template'));

  // 设置模板存放目录 app.setexpress框架进行配置

 app.set('views', path.join(__dirname, 'views'));

  // 渲染模板时不写后缀 默认拼接art后缀

 app.set('view engine', 'art');

 app.get('/', (req, res) => {

     // 渲染模板

     res.render('index');

 });

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第23张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第24张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第25张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第26张图片

4.2 app.locals 对象

不同的页面中,总会有公共数据代码中如何查询公共数据呢

  • 在不同页面路由中 都去查询这个相同的数据,render 将数据填充到模板中,麻烦; 一次,所有能用到都而已拿到这个数据呢?
  • 将变量设置到 app.locals 对象下面,这个数据在所有的模板中都可以获取到。!!!

app.locals.users = [{

     name: '张三',

     age: 20

 },{

     name: '李四',

     age: 20

}]

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第27张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第28张图片

08【Express框架】详细版 - Express框架简介,中间件, Express请求处理,express-art-template模板引擎._第29张图片

 

你可能感兴趣的:(前端学习,中间件,express,前端)