zoukankan      html  css  js  c++  java
  • Node教程——Express框架简约教程

    Express框架学习

    (一导学) 框架入门

    这个也是是一个开发框架,是一个第三方模块,使用这个框架可以很方便的创建网站服务器

    我们先来看看它的特点:
    1.提供了方便简洁的路由定义方式
    2.对获取HTTP请求参数进行了简化处理
    3.对模板引擎支持程度高,方便渲染动态HTML页面
    4.提供了中间件机制有效控制HTTP请求(对请求的拦截)
    5.拥有大量第三方中间件对功能进行扩展

    其实框架就是一些API,学习框架就是学习还有熟悉它的API

    对比一下原生的路由还有获取请求参数的处理实现方式

    • 简单的上手实现
    1. 首先我们的要npm下载
     npm install express
    
    1. 引入express模块,这个返回一个构造函数,它是我们的express核心的api之一
    const express = require('express');
    
    1. 创建服务器 并且监听端口
    2. 创建路由,接受请求
    // 引入express框架
    const express = require('express'); //返回的值 是一个方法!
    // 创建网站服务器
    const app = express();
    
    app.get('/', (req, res) => {
        // send()
        // 1. send方法内部会检测响应内容的类型
        // 2. send方法会自动设置http状态码
        // 3. send方法会帮我们自动设置响应的内容类型及编码
        res.send('Hello. Express');
    })
    
    app.get('/list', (req, res) => {
        res.send({ name: '张三', age: 20 })
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');
    
    

    (二) 中间件

    什么是中间件??这个就是一堆方法,说白了就对请求的预处理。你可以设置多个中间件处理同一个数据流,他们之间有不同的执行处理顺序,中间件就是一个阀门!

    中间件的构成

    主要是有两个部分:Express提供的方法,第二个就是处理函数(回调)
    主要我们这里有一个next

    语法结构

     app.get('/request', (req, res, next) => {
         req.name = "张三";
    //next方法就是是否允许把请求传递给下一个处理中间件,直到结束
    
    next();
     });
     app.get('/request', (req, res) => {
         res.send(req.name);
     });
    

    app.user中间件

    这个是一个中间件,比较特殊,它不区分请求的方式,它必须放在所有的中间件的前面,next非常的重要!他可以移交控制器,如果你写next就会卡着不动弹

    语法实例

    // 引入express框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    // 接收所有请求的中间件
    // app.use 接收请求, 但是不指定请求方式get或者poset,只要哟请求就有这个东西,如何next传递走
    app.use((req, res, next) => {
        console.log('请求走了app.use中间件');
        next()
    })
    
    // 这里我们的第一个请求做了 规定,当客户端访问/request请求的时候走当前中间件
    app.use('/request', (req, res, next) => {
        console.log('请求走了app.use / request中间件')
        next()
    })
    
    // 如果你访问的list那么值钱的user use('/request', (req, res, next)就不会走了
    app.get('/list', (req, res) => {
        res.send('/list')
    })
    
    app.get('/request', (req, res, next) => {
        req.name = "张三";
        next();
    })
    
    app.get('/request', (req, res) => {
        res.send(req.name)
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');
    
    
    

    中间件应用

    运用非常的广泛:

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

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

    自定义404页面

    示例代码块

    // 引入express框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    // // 网站公告
    // app.use((req, res, next) => {
    //     res.send('当前网站正在维护...')
    // })
    
    //只要你想访问管理页面,就拦截下来 判断你是否登录登录了就放开你,没有的话,就戒掉你
    app.use('/admin', (req, res, next) => {
        // 用户没有登录
        let isLogin = true;
        // 如果用户登录
        if (isLogin) {
            // 让请求继续向下执行
            next()
        } else {
            // 如果用户没有登录 直接对客户端做出响应
            res.send('您还没有登录 不能访问/admin这个页面')
        }
    })
    
    app.get('/admin', (req, res) => {
        res.send('您已经登录 可以访问当前页面')
    })
    
    // 这里的逻辑就是:如果你所有的路由页面都没有匹配到就过来这里,告你没有找到对应的资源
    app.use((req, res, next) => { //app.use就是指定匹配路由
        // 为客户端响应404状态码以及提示信息
        res.status(404).send('当前访问的页面是不存在的')
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');
    
    
    

    错误处理中间件

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

    当程序出现错误时,调用next()方法,并且将错误信息通过参数的形式传递给next()方法,即可触发错误处理中间件。

    如何定义一个错误处理中间件?

    • 丢与普通的错误还有支持Promise Api的异步代码如何捕获并且丢给处理中间件?
    // 引入express框架
    const express = require('express');
    const fs = require('fs');
    // 创建网站服务器
    const app = express();
    //注意!我们的错误有两种,一种是同步的错误,一种是异步的错误,处理方式是不一样的。异步错误可以
    //通过回调函数捕获,也可以通过try catch捕获。但是这个不能捕获其他的api
    app.get('/index', (req, res, next) => {
        // throw new Error('程序发生了未知错误')
        fs.readFile('./01.js', 'utf8', (err, result) => {
            if (err != null) {
                next(err)//这个就是异步的解决方式 如果发生了错误就把这个erro传出去给错误处理中间件
            } else {
                res.send(result)
            }
        })
        // res.send('程序正常执行')
    })
    
    // 错误处理中间
    app.use((err, req, res, next) => {
        res.status(500).send(err.message);
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');
    
    
    • 异步函数错误怎么捕获?和处理,注意它不能捕获其他的错误
    
    // 引入express框架
    const express = require('express');
    const fs = require('fs');
    
    const promisify = require('util').promisify;
    
    // 这个的把原理的方法包装了起来,放回一个方法
    const readFile = promisify(fs.readFile);
    // 创建网站服务器
    const app = express();
    
    app.get('/index', async(req, res, next) => {
        try {
            await readFile('./aaa.js')
        } catch (ex) {
            next(ex); //把这个错误传递走
        }
    })
    
    // 错误处理中间
    app.use((err, req, res, next) => {
        res.status(500).send(err.message);
    })
    
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');
    
    
    

    (三) 路由

    构建模块化路由的基础代码

    我们希望把路由分离出去,某些页面的业务处理逻辑是不同的路由

    简单的创建

    // 引入express框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    // 创建路由对象
    const home = express.Router();
    // app.use是一个中间件
    // 为路由对象匹配请求路径
    app.use('/home', home);
    // 创建二级路由
    home.get('/index', (req, res) => {
        res.send('欢迎来到博客首页页面')
    })
    
    // 端口监听
    app.listen(3000);
    
    

    构建模块化路由

    这里指的是把路由分离出去
    主要的代码

    • hoem.js路由
    const express = require('express');
    
    const home = express.Router();
    
    home.get('/index', (req, res) => {
    	res.send('欢迎来到博客首页页面')
    });
    
    module.exports = home;
    
    • admin.js路由
    const express = require('express');
    
    const admin = express.Router();
    
    admin.get('/index', (req, res) => {
    	res.send('欢迎来到博客管理页面')
    });
    
    module.exports = admin;
    
    
    • app.js路由
    // 引入express框架
    const express = require('express');
    // 创建网站服务器
    const app = express();
    
    const home = require('./route/home');
    const admin = require('./route/admin');
    // 配置模块化路由
    
    app.use('/home', home);
    app.use('/admin', admin);
    
    
    // 端口监听
    app.listen(3000);
    
    

    (四) 关于请求的数据处理

    两个对比,一个是原生的实现一个是框架的实现

    如何获取get请求参数

    req.query即可获取GET参数,框架内部会将GET参数转换为对象并返回。

    语法结构

    // 接收地址栏中问号后面的参数
     // 例如: http://localhost:3000/?name=zhangsan&age=30
     app.get('/', (req, res) => {
        console.log(req.query); // {"name": "zhangsan", "age": "30"}
     });
    
    
    
    

    如何获取post请求参数

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

    语法结构

    
     // 引入body-parser模块
     const bodyParser = require('body-parser');
     
     // 配置body-parser模块,拦截所有请求,会把请求转化为对象,然后给这日些对象添加一个属性这个属性叫body。这个extended:false参数是false的时候说明 先用queryString系统模块对参数处理一遍。true的时候使用名为QS的第三方模块 把请求转化为对象
    //  bodyParser.urlencoded({ extended: false })放回的一个函数
     
     app.use(bodyParser.urlencoded({ extended: false }));
     // 接收请求
     app.post('/add', (req, res) => {
        // 接收请求参数
        console.log(req.body);
     }) 
    
    
    

    app.use()里的形参是一个函数~

    验证代码

    
    // 引入express框架
    const express = require('express');
    const bodyParser = require('body-parser');
    // 创建网站服务器
    const app = express();
    // 这个是一个对象,里面是的a是2 {a :2}
    app.use(fn({ a: 2 })) //user可以直接使用函数
    
    function fn(obj) {
        return function(req, res, next) {
            if (obj.a == 1) {
                console.log(req.url)
            } else {
                console.log(req.method)
            }
            next() //移交控制权
        }
    }
    
    //路由
    app.get('/', (req, res) => {
        // 接收post请求参数
        res.send('ok')
    })
    
    // 端口监听
    app.listen(3000);
    
    

    路由参数(这个也是一个请求的处理解析函数)

    这个比较好用,专门拿来做get的参数处理

    这个是比较nb的东西,也是处理请求参数

    
    // 引入express框架
    const express = require('express');
    const bodyParser = require('body-parser');
    // 创建网站服务器
    const app = express();
    
    // 这额: id: name实际上是一个占位符号
    app.get('/index/:id/:name/:age', (req, res) => {
        // 接收post请求参数。这个属性 是expers框架下的构建的,parmas存储的就是一个值对象
    
        res.send(req.params) // 你拿到的是{ id:123 ,name:laoli,age:18 }
    })
    
    //你的发送格式: localhost:3000/index/123/laoli/18
    // 端口监听
    app.listen(3000);
    
    

    (五、资源) 静态资源访问功能

  • 相关阅读:
    backbone.js初体验--构建简单分页应用时踩到的坑
    使用r.js打包js文件
    javascript原型式继承
    javascript浮点数运算修正
    javascript对象的浅复制与深复制
    javascript类式继承
    初识requirejs(二)
    标准版SCADA 上线了~~ 三菱 Fanuc 广数 华中 西门子 HAAS等等 可以做到一套程序通用,采集所有CNC PLC
    KepServerEX读写三菱PLC,车间现场测试记录,带你了解【数据采集的困境】的前世与今生
    Mitsubishi (三菱) Fanuc(发那科),CNC,网口数据采集,NC程序下发(其它品牌CNC,哈斯 马扎克 兄弟等,正在开发中)
  • 原文地址:https://www.cnblogs.com/BM-laoli/p/12673929.html
Copyright © 2011-2022 走看看