初识
由JS组成的技术栈不在需要环境切换了!你再也不同从JS的思维切换到PHP、C#、Ruby、Python...
JS只是个玩具吗?其实大多时候“不是游戏太差,只是玩家太烂”的缘故。
Express 是精简的、灵活的Node.js Web程序框架,为构建单页、多页、混合Web应用提供了一系列健壮的功能特性。
- 精简
框架开发者通常会忘记 “少即是多” 这一基本原则,Express的哲学是在你的想法和服务器之间充当薄薄的一层。这并不意味着它不够健壮,或没有足够的有用特性,而是尽量少干预你,让你充分表达自己的思想,同时提供一些有用的东西。
- 灵活
Express 哲学中另一个关键点是可扩展。Express提供了一个非常精简的框架,你可根据自己的需要添加或替换不能满足你需要的部分。这种做法很新鲜,因为只有在你需要的时候才会去添点东西。
- Web程序框架
Web程序除了网站、网页,它还可向其他Web程序提供功能。程序是具有功能的,它不止是内容的静态集合。
- 单页Web程序
单页Web程序把整个网站(或很大部分)都下载到客户端浏览器上,经过初始下载后,用户访问不同页面的速度更快了,因为几乎无需 与服务端通信。单页程序的开发可使用 Angular或Ember等前端框架,Express跟他们都配合得很好。
- 多页和混合Web程序
多页Web程序是更传统的方式,网站上的每个页面都是通过服务器发起单独的请求得到的。这种方式确实比较传统,单并不意味着它没有优点,只是现在有更多选择了。你可决定哪些内容应该作为单页程序提供,哪些应该通过不同请求提供。混合说的就是同时使用者两种方式的网站。
简史
Express缔造者TJ Holowaychuk 说 Express 是在 Sinatra 的启发下创建的,Sinatra是一个基于Ruby的框架。Express借鉴了一个在Ruby上构建的框架并不奇怪,因为Ruby是一个在致力于让Web开发变得更快、更高效、更可维护、并衍生大量的Web开发方式。
除了Sinatra,Express跟Connect有着紧密的联系,Connect是一个Node的插件库。Connect创造了中间件(middleware)这个术语来描述插入式的Node模块,它在不同程序上处理Web请求。
Express4之前是捆绑Connect的,Express4中Connect被去掉了,以便于中间件可各自独立升级。
一种新型的Web服务器
Node是一种新型的Web服务器,Node实现Web服务器的方式跟Express很像,非常精简,其搭建和配置非常容易。Node和传统服务器之间另一个主要区别在于:Node是单线程的。这是一种倒退吗?事实证明这是天才之举。
单线程极大地简化了Web程序的编写,如果你需要多线程程序的性能,仅需启动更多地Node实例,即可得到多线程的线程优势。
通过服务器并行(性对于程序的并行)的多线程只是把复杂性转移了,并没有消除它啊?
尽管Node所用到Javascript引擎V8确实会将JS编译为本地机器码,但这一操作是透明的。所以从用户角度来看,它表现的像纯粹的解释性语言一样。没有单独的编译步骤,这减少了维护和部署的麻烦。
生态系统
Node处于这个技术栈的核心位置,由于构建一个功能性网站需要借助很多技术,因此衍生了一种用来描述网站架构基础“技术栈”的缩略语。比如Linux、Apache、MySQL、PHP被称为LAMP栈。MongoDB的工程师Valeri Karpov发明了一个缩略语MEAN,指代的是Mongo、Express、Angular、Node。
开始
Node所提供的范式跟传统的Web服务器不同:你写的程序就是Web服务器。Node只是给你提供了一个构建Web服务器的框架。
vim http.js
var http = require('http');
// 事件驱动编程,HTTP请求就是要处理的事件。
http.createServer(function(req,res){
// 内容类型设置为普通文本,并发送字符串
res.writeHead(200, {'Content-Type':'text/plain'});
res.end('Hello world!');
}).listen(3000);
console.log('server started on localhost:3000');
node http.js
事件驱动编程,http.js中事件是隐含的:HTTP请求就是要处理的事件,http.createServer()将函数作为一个参数,每次有HTTP请求发送过来就会调用该函数。这里这是把内容类型设置为普通文本,并发送字符串。
vim http2.js
var http = require('http');
// 事件驱动编程,HTTP请求就是要处理的事件。
http.createServer(function(req,res){
// 规范化URL,去除查询字符串、可选反斜杠后转为小写。
var path = req.ur.replace(/\/?(?:\?.*)?$/, '').toLowerCase();
switch(path){
case '':
res.writeHead(200,{'Content-Type':'text/plain'};
res.end('homepage');
break;
case '/about':
res.writeHead(200,{'Content-Type':'text/plain'};
res.end('about');
break;
default:
res.writeHead(404,{'Content-Type':'text/plain'};
res.end('Not Found');
break;
}
}).listen(3000);
console.log('server started on localhost:3000');
node http.js
省时省力
脚手架
脚手架并不是一个新想法,多数人通过Ruby才接触大这个概念。这个想法很简单,大多数项目都需要一定数量的套路化代码,谁会想每次开始新项目时都重新写一次呢?简答的方式是创建一个通用的项目骨架,每次开始新项目时,仅需复制骨架或模板。
RoR将此概念向前推进了一步,它提供了一个可自动生成脚手架的程序。Express借鉴了RoR的这一做法,提供了一个生成脚手架的工具,从而让你开始一个新的Express项目。
# 安装express
npm install -g express
# 安装脚手架
npm install -g express-generator
# 卸载express
npm uninstall -g express
npm uninstall -g express-generator
# 进入项目目录创建应用
express app
cd app & npm install
# 安装服务器监听工具
npm install -g supervisor
supervisor bin/www
Express是如何工作的呢?
Express是单入口的主文件启动,在Node命令中可启动,它也会以模块的形式存在。
主文件会做些什么事情呢?
- 引入模块
- 配置Express
- 连接数据库
- 定义中间件
- 定义路由
- 启动应用
- 以模块形式输出应用
当前Express的应用运行起来后便开始监听其你去,每个刚来的请求都会根据规定的中间件和路由链自上而下处理。控制好执行流程是非常重要的,例如在文件中上游中的路由或中间件比下游更具优先权。
那么,中间件是什么呢?因为可以在每个HTTP请求过程中添加多个函数来对其进行处理,所以称这些函数为中间件。
中间件能干些什么呢?
- 解析cookie中的信息并将其填入req对象中,供后续的中间件或路由使用。
- 解析URL中的参数并填入req对象供后续中间件或路由使用
- 若用户已认证即拥有cookie或session,可根据他们中参数的值从数据库获得响应,并填入req对象供后续中间件或路由使用。
- 认证或取消认证用户或请求
- 呈现数据并终止响应
Express的核心是中间件
//声明中间件
var cookieParse = require('cookie-parser');//解析HTTP请求中的cookie数据(req.cookie)
var bodyParse = require('body-parser');//解析HTTP请求的body数据(req.body)
//使用中间件
app.use(cookieParser());
app.use(bodyParse.json());
中间件能够对请求做出有用的事情,或提供帮助的独立执行函数。中间件内部包含一连串的函数,这些函数都会对经过它的请求进行不同的处理。
自己编写中间件很简单
app.use(function(req, res, next){
if(req.query.id){
//todo
}else if(req.body.name){
//todo
}else{
//todo
}
next();
})
Express中的路由
app.use('/', routes);
app.use('/users', users);
路由是不区分大小写,默认情况下Express禁止开发人员以字符串查询参数的形式请求路由。
GET:www.junchow.com/?id=1
数据提交方式
- 传统服务端提交方式
被认为是传统搜索引擎的最佳方式,但会让用户(尤其是移动端)等待更久,而且不流畅。 - REST API/AJAX 提交方式
通过REST API或HTTP请求发送或接收,在客户端渲染HTML的方式。被众多前端框架采用,因为它能更好地提高效率和组织代码,因为HTML只需要在客户端进行渲染,传输中只包含数据。