Node中的Connect——常用中间件

本文介绍了Connect内置的多种中间件,包括static、query、logger、bodyparser等,详细讲解了它们的功能及配置方法,并展示了如何利用这些中间件进行Web开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接下来介绍一个Connect内置的一些中间件:

static中间件

  1.挂载
  static允许将任意一个URL匹配到文件系统中任意一个目录。如:将/my-images URL和名为/images的目录对应起来,可以以如下方式进行挂载:

server.use('/my-images', connect.static('/path/to/images'));

  2. maxAge
  static中间件接收一个名为maxAge的选项,这个选项代表一个资源在客户端缓存的时间。对于一些不经常改动的资源来说,我们可以进行缓存,浏览器就无需每次都去请求它了。

server.use('/js', connect.static('/path/to/bundles', {maxAge: 1000000000000}));

  比如,一种Web应用常见的实践方式就是将所有的客户端JavaScript文件都合并到一个文件中,并在文件名中加上修订号。这个时候,就可以设置maxAge选项,让其永远缓存起来。如上述代码。
  3. hidden
  static接收的另一参数hidden。当hidden值为true时,Connect会托管那些文件名以点(.)开始的在UNIX文件系统中被认为是隐藏的文件:

server.use(connect.static('/path/to/resources', {hidden: true}));

query中间件

  使用query中间件,能够通过req.query对象自动获取URL中的查询字符串。如:我们请求url /blog?page=5时,我们获取数据查询字符串 page=5,可以这么使用(req.url变量中存储着URL的值,即 /blog?page=5):

server.use(connect.query);
server.use(function(req, res) {
    // req.query.page == "5"
});

logger中间件

  logger中间件将发送进来的请求信息和发送出去的响应信息打印在终端。
  它提供了以下四种日志格式:
  - default
  - dev
  - short
  - tiny
  如:使用dev日志格式,可以通过如下初始化logger中间的方式:

server.use(connect.logger('dev'));

  dev是一种精准简短的日志格式,能够提供行为以及性能方面的信息,方便测试Web应用。
  logger中间还允许自定义日志输出格式,还能通过动态的req和res来记录头信息。
  下面是完整的可用token:
  - :req[header](如:req[accept])
  - :res[header](如:res[content-length])
  - :http-version
  - :response-time
  - :remote-addr
  - :date
  - :method
  - :url
  - :referrer
  - :user-agent
  - :status
  使用如下:

server.use(connect.logger(':method :remote-addr'));
server.use(connect.logger('type is :res[content-type], length is '
    + ':res[content-length] and it took :response-time ms.'));

  logger还能够自定义token。如,要给请求Content-Type定义一个简写的:type token,可以采用如下方式:

connect.logger.token('type', function(req, res) {
    return req.headers['content-type'];
});

body parser中间件

  1.接收POST数据
  使用body parse中间件可以接收POST请求的数据,并将数据存储到req.body中。如:

server.use(connect.bodyParser());
server.use(function(req, res) {
    // req.body.myinput
});

  2.处理上传
  bodyParser另一功能就是使用formidable模块,它可以让你处理用户上传的文件。如:

var server = connect(
    connect.bodyParser(),
    connect.static('static')
);
server.use(function(req, res, next) {
    if('POST' == req.method && req.body.file) {
        console.log(req.body.file);
        fs.readFile(req.body.file.path, 'utf8', function(err, data) {
            if(err) {
                res.writeHead(500);
                res.end('Error!');
                return;
            }

            res.writeHead(200, {'Content-Type': 'text/html'});
            res.end([
                '<h3>File: ' + req.body.file.name + '</h3>',
                '<h4>Type: ' + req.body.file.type + '</h4>',
                '<h4>Contents:</h4><pre>' + data + '</pre>'
            ].join(''));
        });
    } else {
        next();
    }
});

  3.多文件上传
  在input的name属性上加上[],即

<input type="file" name="files[]"/>
<input type="file" name="files[]"/>

  这个时候为多文件上传,这时req.body.files就包含了一个数组。

  当浏览器发送cookie数据时,会将其写到cookie头信息中。其数据格式和URL中的查询字符串类似。如:

GET /detail HTTP/1.1
Host: 127.0.0.1
Cookie: key1=value1; key2=value2
Accept: */*

  使用cookieParser中间件就可以通过req.cookies对象轻松访问到这些cookie数据:

server.use(connect.cookieParser());
server.use(function(req, res, next) {
    // req.cookies.key1 = "value1";
    // req.cookies.key2 = "value2";
});

会话(session)

  在绝大多数Web应用中,多个请求间共享“用户会话”的概念是非常必要的。它主要通过在浏览器中设置cookie来实现,该cookie信息会在随后所有的请求头信息中被带回到服务器中。
  用户登录的案例:

var connect = require('connect'),
    users = require('./users'); // 这里直接require了JSON文件,不需要使用module.exports对数据进行暴露

var server = connect(
    connect.logger('dev'),
    connect.bodyParser(),
    connect.cookieParser(),
    // 出于安全考虑,在初始化session中间件的时候需要提供secret选项
    connect.session({secret: 'my app secret'}),
    function(req, res, next) {
        if('/' == req.url && req.session.logged_in) {
            res.writeHead(200, {'Content-Type': 'text/html'});
            res.end('Welcome back, <b>' + req.session.name + '</b>.'
                + '<a href="/logout">Logout</a>');
        } else {
            next();
        }
    },
    function(req, res, next) {
        if('/' == req.url && 'GET' == req.method) {
            res.writeHead(200, {'Content-Type': 'text/html'});
            res.end([
                '<form action="/login" method="POST">',
                '<fieldset>',
                '<legend>Please log in</legend>',
                '<p>User: <input type="text" name="user"></p>',
                '<p>Password: <input type="password" name="password"></p>',
                '<button>Submit</button>',
                '</fieldset>',
                '</form>'
                ].join(''));
        } else {
            next();
        }
    },
    function(req, res, next) {
        if('/login' == req.url && 'POST' == req.method) {
            res.writeHead(200);
            if(!users[req.body.user] || req.body.password != users[req.body.user].password) {
                res.end('Bad username/password');
            } else {
                req.session.logged_in = true;
                req.session.name = users[req.body.user].name;
                res.end('Authenticated!');
            }
        } else {
            next();
        }
    },
    function(req, res, next) {
        if('/logout' == req.url) {
            req.session.logged_in = false;
            res.writeHead(200);
            res.end('Logged out!');
        } else {
            next();
        }
    }
);

server.listen(3000);

  其中users.json文件内容如下:

{
    "DreamBoy": {
        "password": "123",
        "name": "梦小白"
    }
}

  为了让session能够在生产环境中也正常工作,我们需要通过Redis来实现一个持久化。

Redis session

  当我们登录成功后,重启node服务器,然后刷新浏览器,会发现需要重新登录,也就是说session失效或或者说不见了。
  原因在于session默认存储在内存中。这意味着session数据存储在内存中时,当进程退出后,session数据自然也就丢失了。
  生产环境中,需要使用一种当应用重启后,还能够将session信息持久化存储下来的机制,如Redis。
  Redis是一个既小又快的数据库,有一个connect-redis模块使用Redis来持久化session数据,这样就让session驻扎到了Node进程之外。
  使用如下(必须要安装好Redis):

var connect = require('connect'),
    RedisStore = require('connect-redis')(connect);

  使用中间件:

server.use(connect.session({store: new RedisStore, secret: 'my secret'}));

methodOverrid中间件

basicAuth中间件

注:暂不说明。

总结

  1. 中间件是串行执行的。
  2. 使用中间件的好处:代码能以此为构建单元进行组织,并且能够获得高复用性。
  3. Connect是实现了中间件这一思路的模块,它为构建更具表达力的中间件提供了基础架构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值