Node 学习之Connect模块及其中间件的使用
一、概述
Connect
是一个基于HTTP服务器的工具集,它提供了一种新的组织代码的方法与请求、响应对象进行交互,称谓中间件(middleware)。
中间件
其实就是一个简单的JavaScript函数,它除了处理req和res请求外,还接收一个next函数来做流控制。
使用中间件的好处:
1. 能够让代码有更强大的表达能力(将应用拆分为更小单元的能力)。
2. 能够实现很好的重用性。
- 示例:/Connect /website
/* 路径:/Connect/website/server.js */
//模块依赖
var http = require('http');
var fs = require('fs');
//创建http服务器
var server = http.createServer(function(req, res){
//检查请求方法是GET且URL是以/images开始,.jpg结束
if('GET' == req.method && './images' == req.url.substr(0,7) && '.jpg' == req.url.substr(-4)){
//检查文件是否存在, __dirname获取当前服务器所在的路径
fs.stat(__dirname + req.url, function(err, stat){
if(err || !stat.isFile()){
res.writeHead(404);
res.end('Not Found !');
return;
}
serve(__dirname + req.url, 'application/jpg');
});
}
//如果URL为'/',则响应index.html
else if('GET' == req.method && '/' == req.url){
serve(__dirname + '/index.html','text/html');
}else{
res.writeHead(404);
res.end('Not Found !');
}
//根据文件路径获取文件内容
function serve(path, type){
res.writeHead(200, {'Content-type':type});
fs.createReadStream(path).pipe(res);
}
});
//监听端口
server.listen(3000);
/* 路径:/Connect/website/index.html */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>website</title>
<style>
h1{
text-align: center;
}
img{
width: 300px;
height: 300px;
margin-left:20px;
}
</style>
</head>
<body>
<h1>Welcom to My Website</h1>
<img src="./images/1.jpg" alt="">
<img src="./images/2.jpg" alt="">
<img src="./images/3.jpg" alt="">
<img src="./images/4.jpg" alt="">
</body>
</html>
- 运行结果
二、中间件介绍及使用
1. static中间件
Connect允许中间件挂载到URL上,static允许将任意一个URL匹配到文件系统中任意一个目录。
参数
{ maxAge:number } : 表示资源在客户端缓存的时间。
{ hidden:true/false } :以(.)开头的被托管的文件在UNIX文件系统中是否隐藏
示例:
//让my-imgURL和名为/images的目录对应起来
server.use('/my-img', connect.static('/path/to/images'));
//将所有的客户端JavaScript文件合并到一个文件中,并在其文件名加上修订号,然后可设置其永远缓存起来
server.use('/js', connect.static('/path/to/buddles), {maxAge;10000000000000});
server.use(connect.static('path/to/resources',{hidden:true});
2. query中间件
用于获取查询字符串中的数据部分。
有时发送给服务器的数据会以查询字符串的形式,使用query中间件,就能通过req.query对象自动获取查询字符串部分的数据。
比如:
req.url == "/blog=posts?page=5"
那么
req.query.page == "5"
3. logger中间件
用于将发送进来的请求信息和发送出去的响应信息打印在终端。
提供了4中日志格式:
default
dev : 简准简短的日志格式,能够提供行为以及性能方面的信息,方便测试Web应用。
short
tiny
使用示例:/Connect/example2
运行结果:(浏览器端)
(控制台)
4. body parser中间件
功能:
1.用于获取POST请求的数据。
用法:server.use(connect.bodyParser)
2.使用formidable模块,处理用户上传的文件。
单文件上传: <input type="file">
多文件上传: <input type="file" name="files[]">
<input type="file" name="files[]">
示例:
/* 路径: /Connect/example3/example3.js */
//模块依赖
var connect = require('connect');
//创建服务器
var server = connect(
connect.bodyParser(),
connect.static('static'),
function(req, res, next ){
if('POST' == req.method && req.body.file){
//添加中间件,查看reqbody.file的值
//console.log(req.body.file);
fs.readFile(req.body.file.path, 'utf-8', 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>Content:</h4><pre>' + data + '</pre>'
].join(''));
});
}else{
next();
}
}
);
//监听端口
server.listen(3003);
/*路径: /Connect/example3/static/index.html */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>example3</title>
</head>
<body>
<!--处理上传的文件-->
<form action="/" method="POST" enctype="multipart/form-data">
<!--单文件上传-->
<input type="file">
<!--多文件上传-->
<input type="file" name="files[]">
<input type="file" name="files[]">
<button>Send file!</button>
</form>
</body>
</html>
运行结果:
4. cookieParser中间件
用于访问Cookie头信息中的值。
由于session数据是存储在内存中的,当进程退出后,session数据就会消失,为了能够将seesion
信息持久化存储下来,就可以使用Redis.
Redis是一个既小又快的数据库,有一个connect-redis模块使用Redis持久化session数据,这样就让session驻扎在Node进程之外。
用法:server.use(connect.session({store:new RediaStore, secret:'my secret' }));
示例:/Connect/example4
运行结果:
使用不对的用户名或密码登录时:
使用正确的用户名和密码登录:
在浏览器重新输入:localhost:3004时,因为之前登录没有退出,所以显示会如下:
控制台记录结果:
5. methodOverride中间件
一些比较早期的浏览器不支持PUT,DELETE,PATCH请求,常见解决办法是GET或POST请求中加一个_method变量来模拟那些请求。
此外,使用methodOverride中间件,就可以让后台的处理程序识别。
6. basicAuth中间件
用户对客户端进行基本的身份验证。
basicAuth使用提供了User,pass作为参数,同时提供一个回调函数告知验证成功还是失败。
示例:
//添加basicAuth
connect.basicAuth(function(user, pass, fn){
process.stdin.write('Allow user \033[96m' + user + '\033[39m' + 'with pass \033[90m' + pass + '\033[39m ? [y/n]: ');
process.stdin.once('data', function(){
if(data[0] == 'y'){
fn(null,{username:user});
}else{
fn(new Error('Unauthorized'));
}
});
});
三、总结:
使用中间件的好处就是代码能够以此为构建单元进行组织,并且弄够获得高复用性。
Connect是一个实现这种思路的模块,它为构建更具表达力的中间件提供了基础构建。