美文网首页
express 学习笔记

express 学习笔记

作者: 梁坤同学 | 来源:发表于2019-12-18 13:36 被阅读0次

    Express 是一个自身功能极简,完全是由路由和中间件构成一个的开发框架。从本质上来说,一个 Express 应用就是在调用各种中间件。

    • 基于 Node.js 平台开发的 "web 开发框架",就是一个 node.js 模块
    • express 的作用:它提供了一系列强大的特征,帮助你创建各种 Web 和移动设备应用
    • express 同时也是 Node.js 的一个模块

    express 特点

    • 实现了路由功能
    • 中间件(函数)功能
    • 对 req 和 res 对象的扩展
    • 可以集成其他模板引擎

    初始化

    新建一个目录myapp,项目初始化

    $ npm init
    

    安装 express

    $ npm install express --save
    

    创建一个hello world实例

    进入myapp目录,创建一个名为app.js,复制以下代码

    var express = require('express');
    var app = express();
    
    app.get('/', function (req, res) {
      res.send('Hello World!');
    });
    
    var server = app.listen(3000, function () {
      var host = server.address().address;
      var port = server.address().port;
    
      console.log('Example app listening at http://%s:%s', host, port);
    });
    

    上面的代码启动一个服务并监听从 3000 端口进入的所有连接请求。他将对所有 (/) URL 或 路由 返回 “Hello World!” 字符串。对于其他所有路径全部返回 404 Not Found。

    通过以下命令行启动

    $ node app.js
    

    然后在浏览器中打开 http://localhost:3000/ 并查看输出结果。

    express生成器

    通过应用生成器工具 express 可以快速创建一个应用的骨架。

    1.安装以下命令

    $ npm install express-generator -g
    

    2.在当前目录创建myapp的应用,运行以下命令

    $ express myapp
    $ cd myapp 
    $ npm install
    > set DEBUG=myapp & npm start
    

    然后在浏览器中打开 http://localhost:3000/ 网址就可以看到这个应用了。

    通过 Express 应用生成器创建的应用一般都有如下目录结构:

    .
    ├── app.js
    ├── bin
    │   └── www
    ├── package.json
    ├── public
    │   ├── images
    │   ├── javascripts
    │   └── stylesheets
    │       └── style.css
    ├── routes
    │   ├── index.js
    │   └── users.js
    └── views
        ├── error.jade
        ├── index.jade
        └── layout.jade
    
    7 directories, 9 files
    

    express路由

    路由(Routing)是由一个 URI(或者叫路径)和一个特定的HTTP方法(GET、POST 等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。每一个路由都可以有一个或者多个处理器函数,当匹配到路由时,这个/些函数将被执行。

    路由的定义由如下结构组成:app.METHOD(PATH, HANDLER)。其中,app 是一个 express 实例;METHOD 是某个 HTTP 请求方式中的一个;PATH 是服务器端的路径;HANDLER 是当路由匹配到时需要执行的函数。

    以下是一些常见的路由代码

    var express = require('express');
    var app = express();
    
    // respond with "hello world" when a GET request is made to the homepage
    app.get('/', function(req, res) {
      res.send('hello world');
    });
    
    // POST method route
    app.post('/', function (req, res) {
      res.send('POST request to the homepage');
    });
    //app.all() 是一个特殊的路由方法,没有任何 HTTP 方法与其对应,它的作用是对于一个路径上的所有请求加载中间件。
    app.all('/secret', function (req, res, next) {
      console.log('Accessing the secret section ...');
      next(); // pass control to the next handler
    });
    

    使用字符串模式的路由路径示例:字符 ?、+、* 和 () 是正则表达式的子集,- 和 . 在基于字符串的路径中按照字面值解释。

    // 匹配 acd 和 abcd
    app.get('/ab?cd', function(req, res) {
      res.send('ab?cd');
    });
    
    // 匹配 abcd、abbcd、abbbcd等
    app.get('/ab+cd', function(req, res) {
      res.send('ab+cd');
    });
    
    // 匹配 abcd、abxcd、abRABDOMcd、ab123cd等
    app.get('/ab*cd', function(req, res) {
      res.send('ab*cd');
    });
    
    // 匹配 /abe 和 /abcde
    app.get('/ab(cd)?e', function(req, res) {
     res.send('ab(cd)?e');
    });
    
    //使用正则表达式的路由路径示例:
    // 匹配任何路径中含有 a 的路径:
    app.get(/a/, function(req, res) {
      res.send('/a/');
    });
    
    // 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man等
    app.get(/.*fly$/, function(req, res) {
      res.send('/.*fly$/');
    });
    

    路由句柄

    可以为请求处理提供多个回调函数,其行为类似 中间件。唯一的区别是这些回调函数有可能调用 next('route') 方法而略过其他路由回调函数。

    路由句柄有多种形式,可以是一个函数、一个函数数组,或者是两者混合,如下所示

    //使用多个回调函数处理路由(记得指定 next 对象):
    app.get('/example/b', function (req, res, next) {
      console.log('response will be sent by the next function ...');
      next();
    }, function (req, res) {
      res.send('Hello from B!');
    });
    
    //使用回调函数数组处理路由:
    
    var cb0 = function (req, res, next) {
      console.log('CB0');
      next();
    }
    
    var cb1 = function (req, res, next) {
      console.log('CB1');
      next();
    }
    
    var cb2 = function (req, res) {
      res.send('Hello from C!');
    }
    
    app.get('/example/c', [cb0, cb1, cb2]);
    

    响应方法

    下表中响应对象(res)的方法向客户端返回响应,终结请求响应的循环。如果在路由句柄中一个方法也不调用,来自客户端的请求会一直挂起。

    方法 描述
    res.download() 提示下载文件。
    res.end() 终结响应处理流程。
    res.JSON() 发送一个 JSON 格式的响应。
    res.jsonp() 发送一个支持 JSONP 的 JSON 格式的响应。
    res.redirect() 重定向请求。
    res.render() 渲染视图模板。
    res.send() 发送各种类型的响应。
    res.sendFile 以八位字节流的形式发送文件。
    res.sendStatus() 设置响应状态代码,并将其以字符串形式作为响应体的一部分发送。

    app.route()

    可使用 app.route() 创建路由路径的链式路由句柄。由于路径在一个地方指定,这样做有助于创建模块化的路由,而且减少了代码冗余和拼写错误。

    app.route('/book')
      .get(function(req, res) {
        res.send('Get a random book');
      })
      .post(function(req, res) {
        res.send('Add a book');
      })
      .put(function(req, res) {
        res.send('Update the book');
      });
    

    express.Router

    可使用 express.Router 类创建模块化、可挂载的路由句柄。Router 实例是一个完整的中间件和路由系统,因此常称其为一个 “mini-app”。

    在 app 目录下创建名为 birds.js 的文件,内容如下:

    var express = require('express');
    var router = express.Router();
    
    // 该路由使用的中间件
    router.use(function timeLog(req, res, next) {
      console.log('Time: ', Date.now());
      next();
    });
    // 定义网站主页的路由
    router.get('/', function(req, res) {
      res.send('Birds home page');
    });
    // 定义 about 页面的路由
    router.get('/about', function(req, res) {
      res.send('About birds');
    });
    
    module.exports = router;
    

    然后在应用中加载路由模块:

    var birds = require('./birds');
    ...
    app.use('/birds', birds);
    

    应用即可处理发自 /birds 和 /birds/about 的请求,并且调用为该路由指定的 timeLog 中间件。

    利用 Express 托管静态文件

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

    将静态资源文件所在的目录作为参数传递给 express.static 中间件就可以提供静态资源文件的访问了。例如,假设在 public 目录放置了图片、CSS 和 JavaScript 文件,你就可以:

    //code from http://caibaojian.com/express-basic.html
    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.static 中间件:

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

    如果你希望所有通过 express.static 访问的文件都存放在一个“虚拟(virtual)”目录(即目录根本不存在)下面,可以通过为静态资源目录指定一个挂载路径的方式来实现,如下所示:

    app.use('/static', express.static('public'));
    

    现在就可以通过带有 “/static” 前缀的地址来访问 public 目录下面的文件了。

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

    常见问题

    1. 处理 404

    在 Express 中,404 并不是一个错误(error)。因此,错误处理器中间件并不捕获 404。这是因为 404 只是意味着某些功能没有实现。也就是说,Express 执行了所有中间件、路由之后还是没有获取到任何输出。你所需要做的就是在其所有他中间件的后面添加一个处理 404 的中间件。如下:

    app.use(function(req, res, next) {
      res.status(404).send('Sorry cant find that!');
    });
    
    1. Express 支持哪些模板引擎?

    Express 支持任何符合 (path, locals, callback) 接口规范的模板引擎。

    1. 渲染纯HTML文件

    不需要!无需通过 res.render() 渲染 HTML。你可以通过 res.sendFile() 直接对外输出 HTML 文件。如果你需要对外提供的资源文件很多,可以使用 express.static() 中间件。

    相关文章

      网友评论

          本文标题:express 学习笔记

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