• Node express 框架


    简介

    Express 是基于 Node.js 平台,快速、开放、极简的 Web 开发框架, 提供一系列强大特性帮助你创建各种Web应用。Express 不对 node.js 已有的特性进行二次抽象,我们只是在它之上扩展了Web应用所需的功能。丰富的HTTP工具以及来自Connect框架的中间件随取随用,创建强健、友好的API变得快速又简单

    官网

    https://www.expressjs.com.cn/

    安装

    首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录。

    通过 npm init 命令为你的应用创建一个 package.json 文件。 欲了解 package.json 是如何起作用的,请参考 Specifics of npm’s package.json handling.

    $ npm init
    

    此命令将要求你输入几个参数,例如此应用的名称和版本。 你可以直接按“回车”键接受大部分默认设置即可,下面这个除外:

    entry point: (index.js)
    

    键入 app.js 或者你所希望的名称,这是当前应用的入口文件。如果你希望采用默认的 index.js 文件名,只需按“回车”键即可。

    image-20201006143242280

    接下来在 myapp 目录下安装 Express 并将其保存到依赖列表中。如下:

    $ npm install express --save
    

    image-20201006143328300

    如果只是临时安装 Express,不想将它添加到依赖列表中,可执行如下命令:

    $ npm install express --no-save
    

    npm 5.0+ 版本在默认情况下会将安装的模块添加到 package.json 文件中的 dependencies 列表中。对于较老的 npm 版本,你就必须指定 --save 参数。然后,照旧执行 npm install 命令即可自动安装依赖列表中所列出的所有模块。

    hello world

    创建app.js 并写入

    const express = require('express');
    const app = express();
    const port = 3000;
    
    app.get('/', function(req, res) {
        res.send('Hello World!')
    });
    
    app.listen(port, function(){
        console.log(`请求访问127.0.0.1:${port}!`)
    });
    

    运行结果

    image-20201006144242479

    到此简单的hello world 已经完成

    使用

    内置路由和外置路由

    内置路由和外置路由简单理解就是把路由写在app.js(入口文件)文件中,还是写在其他文件中,写在app.js文件里就是内置路由其他文件就是外置路由。如上面的hello world案例就是内置路由,不过一般都是使用外置路由。

    route.js

    //引入express 框架模块
    var express = require('express');
    //获取路由对象
    var router = express.Router();
    
    //设置路由
    router.get('/',(req,res)=>{
        res.send('123');
    })
    router.get('/user',(req,res)=>{
        res.send('user');
    })
    router.post('/edit',(req,res)=>{
        res.send('post_edit');
    })
    
    // 导出 路由router
    module.exports = router;
    

    app.js

    var express = require('express');
    var app = express();
    
    // 引入外置路由模块
    var rout = require('./route');
    // 使用引入外置的路由
    app.use(rout);
    
    app.listen('8000',()=>{
        console.log('127.0.0.1:8000')
    })
    

    运行结果

    image-20201006150209015

    使用art-template模板引擎

    art-template@4 新特性

    express-art-template

    在express框架中使用art-template模板引擎还需要安装express-art-template

    安装

    npm install --save art-template
    npm install --save express-art-template
    

    官方示例:

    var express = require('express');
    var app = express();
    app.engine('art', require('express-art-template'));
    app.set('view options', {
        debug: process.env.NODE_ENV !== 'production'
    });
    
    app.get('/', function (req, res) {
        res.render('index.art', {
            user: {
                name: 'aui',
                tags: ['art', 'template', 'nodejs']
            }
        });
    });
    

    Demo

    app.js

    var express = require('express');
    var app = express();
    
    //注册引擎
    app.engine('html', require('express-art-template'));
    
    // 引入外置路由模块
    var rout = require('./route');
    // 使用引入外置的路由
    app.use(rout);
    
    app.listen('8000',()=>{
        console.log('127.0.0.1:8000')
    })
    

    route.js

    //引入express 框架模块
    var express = require('express');
    //获取路由对象
    var router = express.Router();
    
    //设置路由
    router.get('/',(req,res)=>{
        //默认会去当前目录下的views目录下获取静态页面
        res.render('index.html', {title:'express-art-template-title'});
    })
    
    // 导出 路由router
    module.exports = router;
    

    ./views/index.html

    <h1>{{title}}</h1>
    

    运行结果

    image-20201006154222880

    遇到的问题

    模板路径的问题

    image-20201006154422980

    在项目中新建views目录,将所有静态页面放入views目录

    image-20201006154501412

    响应html页面

    之前使用http模块的时候,是用fs读取html文件内容并且设置响应头才可以响应html页面,比较麻烦。那么现在express框架有什么比较简单的办法呢?

    API

    res.sendFile(路径[,选项] [,fn])

    res.sendFile() Express v4.8.0及更高版本受支持。

    在给定的位置传输文件pathContent-Type根据文件名的扩展名设置响应HTTP标头字段。除非root在选项对象中设置了选项,path否则必须是文件的绝对路径

    该API提供对正在运行的文件系统上的数据的访问。确保(a)如果path参数包含用户输入,则将参数构造为绝对路径的方法是安全的;或者(b)将root选项设置为包含访问权限的目录的绝对路径。

    root被提供的选项,所述path参数被允许是相对路径,包括含有..。Express将验证提供的相对路径path是否可以在给定的root选项内解析。

    下表提供了有关该options参数的详细信息。

    属性 描述 默认 可用性
    maxAge Cache-Control以毫秒为单位设置标头的max-age属性,或以ms格式设置字符串 0
    root 相对文件名的根目录。
    lastModified Last-Modified标头设置为操作系统上文件的最后修改日期。设置false为禁用它。 已启用 4.9.0+
    headers 包含要与文件一起使用的HTTP标头的对象。
    dotfiles 用于提供点文件的选项。可能的值为“允许”,“拒绝”,“忽略”。 “忽视”
    acceptRanges 启用或禁用接受远程请求。 true 4.14+
    cacheControl 启用或禁用设置Cache-Control响应头。 true 4.14+
    immutable immutableCache-Control响应头中启用或禁用指令。如果启用,maxAge还应指定该选项以启用缓存。该immutable指令将阻止受支持的客户端在maxAge选项的有效期内提出条件请求,以检查文件是否已更改。 false 4.16+

    fn(err)传输完成或发生错误时,该方法将调用回调函数。如果指定了回调函数并且发生错误,则回调函数必须通过结束请求-响应周期或将控制权传递给下一条路由来显式处理响应过程。

    注意:上面写了除非设置了root选项,否则文件路径必须是绝对路径

    这时候就要使用__dirname这个,来获取当前目录的绝对路径了

    文档:http://nodejs.cn/api/modules/dirname.html

    响应html页面的Demo

    route.js

    //引入express 框架模块
    var express = require('express');
    //获取路由对象
    var router = express.Router();
    
    //设置路由
    router.get('/',(req,res)=>{
       //只能绝对路径
       res.sendFile(__dirname+'/views/index.html');
    })
    
    // 导出 路由router
    module.exports = router;
    

    利用 Express 托管静态文件

    官方文档:http://www.expressjs.com.cn/starter/static-files.html

    为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static内置中间件函数。

    此函数特征如下:

    express.static(root, [options])
    

    The root argument specifies the root directory from which to serve static assets. For more information on the options argument, see express.static.

    例如,通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:

    app.use(express.static('public'))
    

    现在,你就可以访问 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
    

    Express 在静态目录查找文件,因此,存放静态文件的目录名不会出现在 URL 中。

    如果要使用多个静态资源目录,请多次调用 express.static 函数:

    app.use(express.static('public'))
    app.use(express.static('files'))
    

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

    Demo

    1.新建静态资源存放路径,如public

    image-20201006155903524

    2.入口文件中设置静态资源目录

    app.use(express.static('public'))
    

    就可以了

    例:

    app.js

    var express = require('express');
    var app = express();
    
    //设置静态资源目录
    app.use(express.static('public'))
    
    app.listen('8000',()=>{
        console.log('127.0.0.1:8000')
    })
    

    ./public/img/test.jpg

    image-20201006162515399

    访问http://127.0.0.1:8000/img/test.jpg

    image-20201006162628006

    如果是在其他静态页面中使用则直接写

    <img src="/img/test.jpg">
    

    直接写相对于public 的目录下的路径即可

    使用formidable进行文件上传

    npm地址:https://www.npmjs.com/package/formidable

    安装

    npm install formidable
    

    选项

    • options.encoding {string} -默认值'utf-8';设置传入表单字段的编码,
    • options.uploadDir {string} -默认值os.tmpdir();用于放置文件上载的目录。稍后可以使用进行移动fs.rename()
    • options.keepExtensions {boolean} -默认值false;是否包含原始文件的扩展名
    • options.maxFileSize {number} -默认值200 * 1024 * 1024(200mb);限制上传文件的大小。
    • options.maxFields {number} -默认值1000;限制Querystring解析器将解码的字段数,将0设置为无限制
    • options.maxFieldsSize {number} -默认值20 * 1024 * 1024(20mb);限制所有字段(文件除外)可一起分配的内存量(以字节为单位)。
    • options.hash {boolean} -默认值false;包括为传入文件计算的校验和,将其设置为某种哈希算法, 有关可用算法,请参见 crypto.createHash
    • options.multiples {boolean} -默认值false;当您调用该 .parse方法时,files(回调的)参数将包含用于输入的文件数组,这些输入使用HTML5multiple 属性提交多个文件。同样,该fields参数将包含名称以“ []”结尾的字段的值数组。

    普通表单控件和文件表单控件数据结构示例

    普通表单控件

    { name: 'zhangsan' }
    

    image-20201006172128158

    文件表单控件

    {
      file: File {
        _events: [Object: null prototype] {},
        _eventsCount: 0,
        _maxListeners: undefined,
        //文件大小
        size: 57313,
        //文件路径
        path: 'public\upload_aa5dfaec37e92b4efe60ae1cec4d6f2d.jpg',
        //文件名
        name: 'u=313355857,739398057&fm=26&gp=0.jpg',
        //文件类型
        type: 'image/jpeg',
        hash: null,
        //最后修改时间
        lastModifiedDate: 2020-10-06T09:17:13.572Z,
        _writeStream: WriteStream {
          _writableState: [WritableState],
          _events: [Object: null prototype] {},
          _eventsCount: 0,
          _maxListeners: undefined,
          path: 'public\upload_aa5dfaec37e92b4efe60ae1cec4d6f2d.jpg',
          fd: 3,
          flags: 'w',
          mode: 438,
          start: undefined,
          autoClose: true,
          pos: undefined,
          bytesWritten: 57313,
          closed: false,
          [Symbol(kFs)]: [Object],
          [Symbol(kCapture)]: false,
          [Symbol(kIsPerformingIO)]: false
        },
        [Symbol(kCapture)]: false
      }
    }
    

    image-20201006172237589

    Demo

    var express = require('express');
    var fs = require('fs');
    var formidable = require('formidable');
    var app = express();
    
    app.post('/upload',(req,res)=>{
        //创建上传表单
        var form = new formidable.IncomingForm();
    
        //设置
        //formidable的默认保存路径是:“C:UsersAdministratorAppDataLocalTemp”
        //修改formidable 临时存放存储路径为当前目录下的public
        form.uploadDir = './public';
        // 保留文件扩展名
        form.keepExtensions = true;
    
        /**
         * err 表示错误信息
         * fields 表示普通表单控件
         * files 表示文件表单控件
         */
        form.parse(req, function (err, fields, files) {
            console.log(fields);
            console.log(files);
    
            var times = new Date().getTime();
            // 组装上传路径
            var file_path = './public/'+times+files.file.name;
            // 将缓存文件移动至制定目录
            fs.rename(files.file.path,file_path,(err)=>{
                console.log(file_path);
            });
            res.end();
        });
    })
    app.listen('8000',()=>{
        console.log('127.0.0.1:8000')
    })
    

    运行结果

    image-20201006171956784

    使用cookie与session

    express官方资源中,为我们提供了一个中间件,cookie-session

    安装

    npm install cookie-session
    

    Demo

    var express = require('express');
    var cookieSession = require('cookie-session')
    var app = express();
    
    // 注册中间件
    app.use(cookieSession({
        name: 'session', // 客户端cookie的名称
        keys: ['ss'] // 用于加密的关键字
    }))
    
    app.get('/', (req, res) => {
        // 获取并判断session
        if(req.session.sess_data){
            res.send('已经登陆')
        }else{
            // 如果没有session,跳转到登陆页面
            res.send('<script>alert("没登陆");window.location.href="/up"</script>');
        }
    })
    app.get('/up', (req, res) => {
        // 展示登陆页面,获取用户数据并写入session
        req.session.sess_data = {name:12,age:89};
        res.send('已写入session');
    });
    
    app.listen('8000',()=>{
        console.log('127.0.0.1:8000')
    })
    

    这个Demo第一次访问如果没session 会在弹框之后自动写入session

    image-20201007140500022

    再次访问

    image-20201007140525761

    Express的中间件

    什么是中间件

    在一个整体的流程中的某个环节,因为某些原因加入了额外的处理环节;

    中间件的使用

    应用中间件

    语法:

    • app.use()

      • app.use(function(){})

        无论发送任何请求都会执行的中间件

      • app.use('/path', function(){})

        只要在请求path路由时才会执行的中间件(无论GET/POST)

    • app.method()

      • app.get()

        在get请求时会执行的中间件

      • app.post()

        在post请求时会执行的中间件

    app.use() 的用法

    var express = require('express');
    var app = express();
    
    // 在中间件之前,不受中间件影响
    app.get('/',function(req,res){
        console.log(123);
    })
    
    // 应用中间件
    //表示匹配任何路由
    // 请求 '/user' 时,会先调用中间件
    app.use(function (req, res, next) {
        console.log(req);
        next();
    });
    
    // 调用之前先调用中间件
    app.get('/user',function(req,res){
        console.log('user');
    })
    
    app.listen('8000', () => {
        console.log('127.0.0.1:8000')
    })
    

    app.method() 的用法

    var express = require('express');
    var app = express();
    
    // 在中间件之前,不受中间件影响
    app.get('/',function(req,res){
        console.log(123);
    })
    
    // 应用中间件,也叫路由中间件
    // 只有在 post 请求user 时才起作用
    app.post('/user',function (req, res, next) {
        console.log(req);
        //表示匹配完成这个中间件就继续往下执行。
        next();
    });
    
    // 调用之前先调用中间件
    // 接受所有请求方式请求user
    app.all('/user',function(req,res){
        console.log('user');
    })
    
    app.listen('8000', () => {
        console.log('127.0.0.1:8000')
    })
    

    路由中间件

    路由器层中间件的工作方式与应用层中间件基本相同,差异之处在于它绑定到 express.Router() 的实例。

    使用 router.use()router.METHOD() 函数装入路由器层中间件;

    例:

    var app = express();
    var router = express.Router();
    
    //没有挂载路径的中间件。这段代码对每个发送到路由器的请求都执行
    router.use(function (req, res, next) {
      console.log('Time:', Date.now());
      next();
    });
    
    //中间件子堆栈向/user/:id路径显示任何类型的HTTP请求的请求信息
    router.use('/user/:id', function(req, res, next) {
      console.log('Request URL:', req.originalUrl);
      next();
    }, function (req, res, next) {
      console.log('Request Type:', req.method);
      next();
    });
    
    // 处理/user/:id路径的GET请求的中间件子堆栈
    router.get('/user/:id', function (req, res, next) {
      // 如果用户ID为0,则跳到下一个路由器
      if (req.params.id == 0) next('route');
      // 否则,将控制权传递给该堆栈中的下一个中间件函数
      else next(); //
    }, function (req, res, next) {
      // 呈现常规页面
      res.render('regular');
    });
    
    // 用于/user/:id路径的处理程序,它将呈现一个特殊的页面
    router.get('/user/:id', function (req, res, next) {
      console.log(req.params.id);
      res.render('special');
    });
    
    // 使用路由
    app.use('/', router);
    
    

    内置中间件

    express.static 外,先前 Express 随附的所有中间件函数现在以单独模块的形式提供:中间件函数的列表

    Express 中唯一内置的中间件函数是 express.static。此函数基于 serve-static,负责提供 Express 应用程序的静态资源。

    对于每个应用程序,可以有多个静态目录:

    app.use(express.static('public'));
    app.use(express.static('uploads'));
    app.use(express.static('files'));
    

    第三方中间件

    使用第三方中间件向 Express 应用程序添加功能。

    安装具有所需功能的 Node.js 模块,然后在应用层或路由器层的应用程序中将其加装入。

    var cookieSession = require('cookie-session');
    
    // 注册中间件 
    app.use(cookieSession({
        name: 'session', // 客户端cookie的名称
        keys: ['xilingzuishuai'] // 用于加密的关键字
    }))
    
  • 相关阅读:
    18个功能强大的HTML5 和JavaScript游戏引擎库
    10 个超棒的 jQuery 视频插件
    HTML5播放视频音频
    CSS代码重构与优化之路
    推荐10款web前端的 HTML5 开发框架和开发工具
    JS中日期相关函数
    技术笔记1:java.sql.SQLException: Access denied for user 'root'@'localhost' (using password)
    图解HTTP阅读笔记(1)-网络基础TCP/IP
    框架和设计模式的区别
    SSH与MVC
  • 原文地址:https://www.cnblogs.com/makalochen/p/13777309.html
Copyright © 2020-2023  润新知