一、express底层:http模块

  Express框架建立在node.js内置的http模块上。http模块生成服务器的原始代码如下。

var http = require("http");var app = http.createServer(function(request, response) {response.writeHead(200, {"Content-Type": "text/plain"});response.end("Hello world!");
});app.listen(3000, "localhost");

  上面代码的关键是http模块的createServer方法,表示生成一个HTTP服务器实例。该方法接受一个回调函数,该回调函数的参数,分别为代表HTTP请求和HTTP回应的request对象和response对象。

  Express框架的核心是对http模块的再包装。上面的代码用Express改写如下。

var express = require('express');
var app = express();app.get('/', function (req, res) {res.send('Hello world!');
});app.listen(3000);

  比较两段代码,可以看到它们非常接近。原来是用http.createServer方法新建一个app实例,现在则是用Express的构造方法,生成一个Epress实例。两者的回调函数都是相同的。Express框架等于在http模块之上,加了一个中间层。

二、express中间件

  简单说,中间件(middleware)就是处理HTTP请求的函数。它最大的特点就是,一个中间件处理完,再传递给下一个中间件。App实例在运行过程中,会调用一系列的中间件。

  每个中间件可以从App实例,接收三个参数,依次为request对象(代表HTTP请求)、response对象(代表HTTP回应),next回调函数(代表下一个中间件)。每个中间件都可以对HTTP请求(request对象)进行加工,并且决定是否调用next方法,将request对象再传给下一个中间件。

  一个不进行任何操作、只传递request对象的中间件,就是下面这样。

function uselessMiddleware(req, res, next) {next();
}

  上面代码的next就是下一个中间件。如果它带有参数,则代表抛出一个错误,参数为错误文本。

function uselessMiddleware(req, res, next) {next('出错了!');
}

  抛出错误以后,后面的中间件将不再执行,直到发现一个错误处理函数为止。

  在 Node.js Web 开发中,各种模块基本采用这样的中间件格式:

function (req, res, next) {// req 用于获取请求信息, ServerRequest 的实例// res 用于响应处理结果, ServerResponse 的实例// next() 函数用于将当前控制权转交给下一步处理,如果给 next() 传递一个参数时,表示出错信息
}

  Express 是基于 Connect 的, Connect 中间件采用了以上的这种格式。 因此,当你要编写一个中间件时,编写一个以上格式的函数即可。

  其实跟编写 Express 的路由处理函数是没多大区别的,一些细微的差别是:

  • 中间件一般不直接对客户端进行响应,而是对请求进行一些预处理,再传递下去;
  • 中间件一般会在路由处理之前执行;

  比如:

// 检查用户是否登录中间件,所有需要登录权限的页面都使用此中间件
function checkLogin (req, res, next) {if (req.session.user) {next();} else {res.redirect('/');}
} 

三、USE方法

  use是express注册中间件的方法,它返回一个函数。下面是一个连续调用两个中间件的例子。

var express = require("express");
var http = require("http");var app = express();app.use(function(request, response, next) {console.log("In comes a " + request.method + " to " + request.url);next();
});app.use(function(request, response) {response.writeHead(200, { "Content-Type": "text/plain" });response.end("Hello world!\n");
});http.createServer(app).listen(1337); 

  上面代码使用app.use方法,注册了两个中间件。收到HTTP请求后,先调用第一个中间件,在控制台输出一行信息,然后通过next方法,将执行权传给第二个中间件,输出HTTP回应。由于第二个中间件没有调用next方法,所以request对象就不再向后传递了。

use方法内部可以对访问路径进行判断,据此就能实现简单的路由,根据不同的请求网址,返回不同的网页内容。

var express = require("express");
var http = require("http");var app = express();app.use(function(request, response, next) {if (request.url == "/") {response.writeHead(200, { "Content-Type": "text/plain" });response.end("Welcome to the homepage!\n");} else {next();}
});app.use(function(request, response, next) {if (request.url == "/about") {response.writeHead(200, { "Content-Type": "text/plain" });} else {next();}
});app.use(function(request, response) {response.writeHead(404, { "Content-Type": "text/plain" });response.end("404 error!\n");
});http.createServer(app).listen(1337); 

  上面代码通过request.url属性,判断请求的网址,从而返回不同的内容。注意,app.use方法一共登记了三个中间件,只要请求路径匹配,就不会将执行权交给下一个中间件。因此,最后一个中间件会返回404错误,即前面的中间件都没匹配请求路径,找不到所要请求的资源。

  除了在回调函数内部,判断请求的网址,use方法也允许将请求网址写在第一个参数。这代表,只有请求路径匹配这个参数,后面的中间件才会生效。无疑,这样写更加清晰和方便。

app.use('/', someMiddleware); 

  上面代码表示,只对根目录的请求,调用某个中间件。

  因此,上面的代码可以写成下面的样子。

  

var express = require("express");
var http = require("http");var app = express();app.use("/", function(request, response, next) {response.writeHead(200, { "Content-Type": "text/plain" });response.end("Welcome to the homepage!\n");
});app.use("/about", function(request, response, next) {response.writeHead(200, { "Content-Type": "text/plain" });response.end("Welcome to the about page!\n");
});app.use(function(request, response) {response.writeHead(404, { "Content-Type": "text/plain" });response.end("404 error!\n");
});http.createServer(app).listen(1337);

  参考资料:

  http://javascript.ruanyifeng.com/nodejs/express.html

  

express运行原理相关推荐

  1. Serverless 实战 —— Serverless 的运行原理与组件架构

    Serverless 的运行原理与组件架构 本文重点探讨下开发者使用 Serverless 时经常遇到的一些问题,以及如何解决 过去一年,我们和大量 Serverless 用户进行了线上和线下的交流, ...

  2. Asp.net WebPages框架运行原理浅析(转)

    在Asp.net4和4.5中,新增了WebPages Framework,编写页面代码使用了新的Razor语法,代码更加的简洁和符合Web标准,编写方式更接近于PHP和以前的Asp,和使用 WebFo ...

  3. Servlet运行原理以及生命周期

    Servlet运行原理 Servlet生命周期定义了一个Servlet如何被加载.初始化,以及它怎样接收请求.响应请求,提供服务.在讨论Servlet生命周期之前,先让我们来看一下这几个方法: 1. ...

  4. ASP.NET运行原理

    一个ASP.NET的应用程序是开始于IIS的. 当你请求一个包含ASP.NET应用的网址时,IIS接受到请求(IIS是WEB服务守候进程),IIS收到请求后,会根据请求者请求的主机头或者IP或者端口号 ...

  5. Linux X Window System运行原理和启动过程

    本文主要说明X Window System的基本运行原理,其启动过程,及常见的跨网络运行X Window System. 一) 基本运行原理 X Window System采用C/S结构,但和我们常见 ...

  6. 10分钟了解Flutter跨平台运行原理!

    导语 | 本文将从选型.简介和运行原理三大部分为你介绍Flutter的相关概念,希望能站在框架设计和实现原理的高度,带领大家去理解Flutter区别其他跨平台解决方案的关键所在. 一.为什么选择Flu ...

  7. spark on yarn 完全分布式_Spark编程笔记(1)-架构基础与运行原理

    引言 根据IBM前首席执行官郭士纳的观点,IT领域每隔十五年就会迎来一 次重大变革 .当前我们正处于第三次信息浪潮(2010年前后),物联网.云计算和大数据技术突飞猛进. 信息爆炸是我们当前所需要解决 ...

  8. fusion 360安装程序的多个实例正在同时运行。_SpringMVC运行原理

    1. spring mvc简介与运行原理 Spring的模型-视图-控制器(MVC)框架是围绕一个DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器,并支持可配置的 ...

  9. Android开发学习笔记(二)——编译和运行原理(1)

    接着上一篇的内容,继续从全局了解Android.在清楚了Android的平台架构(可以看作是静态原理)后,还需要掌握其动态原理.动态原理包含两部分,一部分是编译原理,另一部分是运行原理.有人会说,搭建 ...

最新文章

  1. 光谱投影颜色感知器件与围栅多桥沟道晶体管技术
  2. yii2model 基本模型类
  3. [TJOI2018]xor
  4. 157. Leetcode 674. 最长连续递增序列 (贪心算法-进阶题目)
  5. MongoDB最新4.2.7版本三分片集群修改IP实操演练
  6. Derangement(AtCoder-3525)
  7. 好看的css3用户基本信息卡片样式源码
  8. android调用python模块 chaquo_小猿圈python学习-系统调用os模块
  9. chkconfig、mount、shutdown
  10. join为什么每个字符都分割了 js_js如何截取以逗号隔开的字符串
  11. 中国电信联合多方加速推进OpenStack技术产业化 —— OSCAR即将发布“OpenStack技术应用场景”技术规范...
  12. Android gallery 3D效果
  13. KVM虚拟化技术介绍以及相关操作
  14. Android仿微信地图定位和位置选择(上)
  15. 史上最强Java生成chm的教程(上)
  16. 什么样的Python培训机构才是好机构?
  17. 服务器挂硬盘 BIOS,TaiShan服务器通过BIOS格式化硬盘将硬盘中的残留数据擦除操作方法...
  18. python实例:井字棋
  19. ps -aux | grep 用法详解
  20. 利用360wifi实现树莓派无线上网

热门文章

  1. Android 读取xml转json,将XML转换为Android中的JSON对象
  2. 兵器工业计算机应用研究所刘培志,一种双目视觉立体匹配算法_2
  3. matlab 神经网络预测时间序列示例(水痘模型)
  4. Squid代理服务器(二)
  5. Sql 先进先出计算积分
  6. WordPress实践:自定义theme(01)
  7. GO语言基础之reflect反射
  8. 《从缺陷中学习C/C++》——6.18 小结
  9. WCF系列(一) -- 完全不使用配置文件构建和使用WCF服务
  10. 【深入浅出Node.js系列十一】Node.js开发框架Express4.x