博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Node] 重要外部模块
阅读量:6966 次
发布时间:2019-06-27

本文共 5681 字,大约阅读时间需要 18 分钟。

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('
 ' +           '
' +           'Your Name: 
' +           '
' + ''});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对象,可以在浏览器里放置一些代码来与服务器交互,例如:

可以使用命名空间把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应用上的客户端代码:

      
    
  

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

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    });  });});

转载地址:http://swisl.baihongyu.com/

你可能感兴趣的文章
[剑指offer] 二叉搜索树与双向链表
查看>>
Java集合框架源码解析之LinkedHashMap
查看>>
读《学习之道》— 放松点,有时候太勤奋也是一种病
查看>>
王者荣耀使用什么编程语言开发的?
查看>>
Kubernetes-离线部署Kubernetes 1.9.0
查看>>
实验吧---忘记密码了
查看>>
C/C++中int128的那点事
查看>>
JAVA中Sql时间格式与util时间格式转换
查看>>
前端概述及网页入门
查看>>
Java Servlet web.xml 配置详解
查看>>
javascript mvc 代码
查看>>
七牛镜像存储使用手册
查看>>
iOS学习笔记之 Objective-C (二)
查看>>
eclipse提交项目到github
查看>>
小米正式开源 Istio 管理面板 Naftis
查看>>
小白们不要慌,这里为你提供免费靠谱的python学习流程图
查看>>
利用种子文件对windows7的攻击-学习笔记
查看>>
微信小程序中异步处理终极方案async/await
查看>>
Java 面向对象 之 方法的覆盖
查看>>
开发者应该了解Kubernetes对于程序的影响点
查看>>