1. Express

Express(Node的MVC框架)是使用最广泛的Node模块,它吸取了Ruby的Sinatra框架的精髓,并提供了许多功能。

Express使用路由定义的页面处理器来工作。路由可以是一个简单的路径,也可以比较复杂,例如:

var express = require('express');
var app = express.createServer();
app.get('/', function(reg, res) {res.send('hello world');
});
app.listen(9000);

app.get()为特定路由创建了响应函数。与一般http服务器不同,Express不是为一般的请求提供监听器,而是针对特定的HTTP动作提供监听器。所以get()只会响应GET请求,put()请处理PUT请求。Express增加了send()方法,我们不需要手动提供HTTP头或是调用end()方法,send()会处理好相关操作。

路由可以包含一个简单的字符串或一个正则表达式,并且可以包含变量声明、通配符及可选关键字标记,例如:

var express = require('express');
var app = express.createServer();
app.get('/:id?', function(req, res) {if (req.params.id) {res.send(req.params.id);} else {res.send('oh hai');}
});
app.listen(9000);

在Express路由中,使用冒号":"来标记想要使用的变量,那么在URL中传递的字符串就会被捕获并保存在该变量中。Express中的所有路由最终都会转变成正则表达式来处理,并进行分词操作以便于应用代码的使用。

Express路由将"/"视作一个标记,而同时又会把请求末尾的"/"当做可选项,所以路由"/:id?"会匹配localhost,localhost/,localhost/tom,localhost/tom/,但不包括localhost/tom/tom。

路由中也可以使用通配符,比如"*"会匹配所有的内容,直到下一个标记出现(非贪心的正则匹配)。与其他正则语言不同的是,"*"表示的不是零个以上的字符,它表示的是一个以上字符。

路由是按顺序执行的,当多个路由同时匹配上提供的URL时,只有第一个匹配的路由会执行相关的动作。如果想从URL中提取变量,需要用正则的语法进行处理,例如:

var express = require('express');
var app = express.createServer();
app.get(/\/(\d+)/, function(req, res) {res.send(req.params[0]);
});
app.listen(9000);

也可以在路由的正则匹配时指定变量的命名,例如:

var express = require('express');
var app = express.createServer();
app.get('/:id(\\d+)', function(req, res) {res.send(req.params[0]);
});
app.listen(9000);

有时会希望同一个URL在不同的情景下匹配多个路由,路由定义的顺序会决定哪个路由被选中使用,但也有办法可以把控制权传给下一个路由,例如:

app.get('/users:id', function(req, res, next) {var id = req.params.id;if (!checkPermission(id)) {next();}
});

next参数会通知路由中间件去调用下一个路由,这个参数总是会传递给回调函数,只不过上例中第一次为它命名并使用它。这还能与app.all()方法很好地配合,它表示所有的HTTP动作都进行处理,例如:

var express = require('express');
var app = express.createServer();
var users = [{name: 'tj'}, {name: 'tom'}];
app.all('/user/:id/:op?', function(req, res, next) {req.user = user[req.params.id];if (req.user) {next();} else {next(new Error('Cannot find user'));}
});
app.get('/user/:id', function(req, res) {res.send('Viewing ' + req.user.name);
});
app.get('/user/:id/edit', function(req, res) {res.send('Editing ' + req.user.name);
});
app.put('/user/:id', function(req, res) {res.send('Updateing ' + req.user.name);
});
app.get('*', function(req, res) {res.send('Danger, Will Robinson!', 404);
});
app.listen(9000);

Express中以Ruby on Rails的风格来提供RESTful的架构的,可以让表单进行各种操作:PUT(替换数据)、POST(创建数据)、DELETE(删除数据)和GET(获取数据),例如:

var express = require('express');
var app = express.createServer();
app.user(express.limit('lmb'));
app.user(express.bodyParser());
app.user(express.methodOverride());
app.get('/', function(req, res) {res.send('<form method="post" action="/"> ' +'<input type="hidden" name="_method" value="put" />' +'Your Name: <input type="text" name="username" />' +'<input type="submit" />' + '</form>'
});
app.put('/', function(req, res) {res.send('Welcome ' + req.body.username);
});
app.listen(9000);

bodyParse()方法会解析从Web浏览器发送来的请求正文,并把表单变量转换成Express使用的对象。methodOverride()方法允许表单提交隐藏的_method变量,并把GET方法替换掉,然后调用相应的RESTful方法类型。express.limit()方法指定Express把请求正文的大小限制在1MB以内。

以上例子中包含了看起来无关的函数app.use(),这个函数调用了Connect库,并提供了许多有用的工具,使得添加功能很容易。因此在此需要介绍中间件以及它为什么对开发Express程序如此重要。

中间件指的是链接两个程序的一个软件,并且通常是更高级的程序间或更宽广的网络间的软件。Connect库提供了Express使用的中间件功能,Express中从Connect继承下来的,同时获得了http和connect的功能。任何添加到Connect的模块都会自动被Express所使用。

Express的路由功能会在处理环节使用内部的中间件,可以通过重载来添加额外的功能,例如:

var express = require('express');
var app = express.createServer(express.cookieParser(),express.session({secret: 'secret key'})
);
var roleFactory = function(role) {return function(req, res, next) {if (req.session.role && req.session.role.indexOf(role) != -1) {next();} else {res.send('You are not authenticated.');}}
}
app.get('/', roleFactory('admin'), function(req, res) {res.send('Welcome to Exrpess!');
});
app.get('/auth', function(req, res) {req.session.role = 'admin';res.send('You have been authenticated.');
});
app.listen(9000);

2. Socket.IO

Socket.IO是一个小巧的扩展库,功能像Node的核心库net,可以通过Socket.IO在浏览器客户端与Node服务器之间采用高效的底层socket机制来回发送消息。它的另一个优点是,可以在浏览器与服务器之间共享代码,例如:

var http = require('http');
var io = require('socket.io');
server = http.createServer();
server.on('request', function(req, res) {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('Hello World');
});
server.listen(80);
socket = io.listen(server);
socket.on('connection', function(client) {console.log('Client connected');
});

Socket.IO并不关心HTTP服务器做什么,它只是把自带的事件监听器包装在发送到服务器的所有请求上,该监听器会查找从Socket.IO客户端发送过来的请求,并以塘沽 处理。

因为socket是持久性连接,所以不需要像HTTP服务器那样处理req和res对象,可以在浏览器里放置一些代码来与服务器交互,例如:

<!DOCTYPE html>
<html>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>var socket = io.connect('http://localhost:80');socket.on('message', function(data) {console.log(data)});
</script>
</body>
</html>

可以使用命名空间把Socket.IO的监听器区分到频道中,避免导致意外冲突,例如:

var http = require('http');
var io = require('socket.io');
server = http.createServer();
server.on('request', function(req, res) {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('Hello World');
});
server.listen(80);
socket = io.listen(server);
socket.of('/space1').on('connection', function(client) {console.log('Client connected to space1');
});
socket.of('/space2').on('connection', function(client) {console.log('Client connected to space2');
});

如果同时使用Express和Socket.IO,将会在使用统一的语言编写整个软件结构方面获得巨大的便利,如下演示一个Socket.IO绑定到Express应用上的客户端代码:

<!DOCTYPE html>
<html><body><script src="/socket.io/socket.io.js"></script><script>var socket = io.connect('http://localhost:80');socket.on('news', function(data) {document.write('<h1>' + data.title + '</h1>');document.write('<p>' + data.contents + '</p>');if (data.allowResponse) {socket.emit('scoop', {contents: 'New data received by client.'});}});</script></body>
</html>

对应的服务器端代码如下:

var app = require('express').createServer();
var io = require('socket.io').listen(app);
app.listen(80);
app.get('/', function(req, res) {res.sendfile(__dirname + '/socket_express.html');
});
io.socket.on('connection', function(socket) {socket.emit('news', {title: 'Welcom to World News',contents: 'This news flash was sent from Node.js!',allowResponse: true;});socket.on('scoop', function(data) {socket.emit('news', {title: 'Circular Emissions Worked',contents: 'Received this content: ' + data.contents});});
});

[Node] 重要外部模块相关推荐

  1. node.js中模块_在Node.js中需要模块:您需要知道的一切

    node.js中模块 by Samer Buna 通过Samer Buna 在Node.js中需要模块:您需要知道的一切 (Requiring modules in Node.js: Everythi ...

  2. Node.js:模块查找,引用及缓存机制

    1. Node.js的模块载入方式与机制 Node.js中模块可以通过文件路径或名字获取模块的引用.模块的引用会映射到一个js文件路径,除非它是一个Node内置模块.Node的内置模块公开了一些常用的 ...

  3. 模块加载及第三方包:Node.js模块化开发、系统模块、第三方模块、package.json文件、Node.js中模块的加载机制、开发环境与生产环境、cookie与session

    1.Node.js模块化开发 1.1 JavaScript开发弊端 JavaScript 在使用时存在两大问题,文件依赖和命名冲突. 1.2 软件中的模块化开发 一个功能就是一个模块,多个模块可以组成 ...

  4. ant design pro 加载慢_ant design pro (九)引入外部模块

    一.概述 除了 antd 组件以及脚手架内置的业务组件,有时我们还需要引入其他外部模块,这里以引入富文本组件 react-quill 为例进行介绍. 二.使用 2.1.引入依赖 在终端输入下面的命令完 ...

  5. Node.js中模块加载机制

    Node.js中模块加载机制 模块查找规则-当模块拥有路径但没有后缀时 1. require方法根据模块路径查找模块,如果是完整路径,直接引入模块. 2. 如果模块后缀省略,先找同名JS文件再找同名J ...

  6. Node.js Web 模块

    Node.js Web 模块 什么是 Web 服务器? Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,Web服务器的基本功能就是提供Web信息浏览服务.它只需支持HTTP协议. ...

  7. 第二章. node中的模块和require

    2019独角兽企业重金招聘Python工程师标准>>> 一 什么是模块. JavaScript诞生初,它只不过是一个网页的小脚本而已,没有人会想到它会发展到现在能有大量的库,工具,组 ...

  8. Node.js Domain 模块

    Node.js 工具模块 Node.js Domain(域) 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的异常.引入 Domain 模块 语法格式如下: var domain = ...

  9. Node.js DNS 模块

    Node.js 工具模块 Node.js DNS 模块用于解析域名.引入 DNS 模块语法格式如下: var dns = require("dns") 方法 序号 方法 & ...

最新文章

  1. LeetCode刷题-1
  2. linux 下的lamp的简单安装
  3. python输入一组身高_一起学Python系列之用户输入
  4. Spring4+SpringMVC+MyBatis整合思路
  5. c语言程序 用追赶法求解方程组,编写用追赶法解三对角线性方程组的程序,并解下列方程组(3页)-原创力文档...
  6. Office 365身份认证管理-添加并验证联合认证域
  7. linux wheel用户组,Linux的用户和组之详解用户和组的分类
  8. linux上pyenv卸载,在Ubuntu 18.04系统下安装pyenv的方法
  9. 软件测试工作中如何有效沟通
  10. Python报错:AttributeError
  11. python学到什么程度可以找到工作-月薪2万+的Python Web岗,学到什么程度能找到工作?...
  12. Java设计模式(10)代理模式(Proxy模式)
  13. 安装opencv_contrib-3.4.9, fatal error: opencv2/xfeatures2d.hpp: 没有那个文件或目录. 解决方法
  14. java缓存技术的介绍
  15. 哪个软件测试交易系统好用,交易系统测试结果的可信度检验
  16. 【3D视觉】深度摄像头与3D重建
  17. 神工鬼斧惟肖惟妙,M1 mac系统深度学习框架Pytorch的二次元动漫动画风格迁移滤镜AnimeGANv2+Ffmpeg(图片+视频)快速实践
  18. Flutter中的widget
  19. mysql出现2058_解决yog连接mysql出现2058的问题
  20. 读书笔记:《群论彩图版》

热门文章

  1. 深入理解 Android Https
  2. Python操作数据库之 MySQL
  3. 《Linux嵌入式实时应用开发实战(原书第3版)》——3.5 Linux文件系统
  4. 核心路由器聚焦三大关键点
  5. 每天一点Linux --- 目录的可执行权限
  6. HDOJ_ACM_折线分割平面
  7. SQL Server中的GAM页和SGAM页
  8. JSON与JAVA数据的转换
  9. SQL Server 2005 Analysis Services
  10. 不是不去爱,爱了也是一种伤害!