Express简介

Node.js简介

在介绍Express之前,先得讲讲Node.js(后文中简称为Node)。

简单来说,Node就是一个JavaScript(后文简称JS)的运行环境。它有如下一些特性:

  1. 基于Chrome V8。这是谷歌开发的非常高效的JS引擎(运行环境),所以Node也十分高效。
  2. Node采用异步的运行机制。这种异步机制使得Node的效率进一步提高,并且能够避免很多并发错误。
  3. Node将JS带到了浏览器之外。这就意味着JS也可以用于服务器端的开发,使得前后端能够使用同样的语言、经验技巧、编程模式甚至代码,极大地拓展了JS程序员的用武之地。

正因为此,有人提出了MEAN或者MERN这样的全JS技术栈。其中的N指的就是Node;而M代表MongoDB,目前最流行的NoSQL数据库之一,它的原生交互壳也是由JS写成的;A和R分别代表AngularJS和React,前者是基于JS的前端框架,后者是用于创建UI的JS库;最后的E,不用说,就是本书的主题Express了。

那么,它到底是什么呢?

Express初会

Express,简单来说就是一个用来创建网络应用框架。加粗的两个词是关键。

所谓“网络应用”,可以理解为响应用户请求、返回相应的内容的程序,很多语境下可以简单等同于服务器。

而“框架”,说明使用者必须按照它的规定行事。但Express属于轻量级,并不特别严格。这意味着Express使用起来非常灵活,比如它适宜开发任何类型的网络应用,也可以和各种各样的第三方模块或者库来使用,甚至在其之上还有很多人开发了更加严格的框架。

事实上,Node本就自带有网络相关的功能(内置模块),加上其他各种功能的第三方模块,不需要什么框架,也可以写出功能足够完备的网络应用。

不过,Node身为JS的运行环境,其网络功能毕竟太过基础。而Express则建立在Node的基础之上,提供了两大便利:

  1. 简化了Node网络编程的API,并且添加了很多新的功能特性。
  2. 能使网络应用的组织更加清晰,更易创建和维护。

在深入讲解这些特性之前,我们先仅用Node写一个简单的网络应用,借机来:

  1. 熟悉/回顾相关的网络基础知识
  2. 熟悉/回顾Node的基础知识
  3. 理解Node的http模块的工作流程。通过对比其中异同,这将有助于我们后面理解Express的工作流程

用Node写网络应用

网络基础知识

首先是一丁点相关的网络基础知识。

http://www.example.com:3000/somewhere?p1=v1&p2=v2#heading2这个URL里:

  • http称为protocol
  • www.example.com称为host
  • 3000称为port,HTTP的网页服务默认端口是80
  • /somewhere?p1=v1&p2=v2称为path(注意这里包括那个撇斜),而其中:
    • p1=v1&p2=v2称为query
    • p1p2叫做parameter,v1v2是它们各自的值
  • #heading2称为fragment,这一部分只存在于浏览器,不会发送给服务器端

另外,一个典型的HTTP客户端请求(client request)长成下面的样子:

GET /somewhere?p1=v1&p2=v2 HTTP/1.0
Host: www.example.com

其中第一行称为request line,依次包括method、path、version三个部分。

请求行下面一般有几行(或者没有)头字段(header field)。

而头字段之后一定会有一行空白,表示没有其他的头字段了。上面没有很好地表现出来。空白行之后可以附带其他消息体。

类似的,一个典型的回复HTML文本的HTTP服务器应答(server response)如下:

HTTP/1.1 200 OK
Content-Length: 23
Date: Wed, 15 Jun 2016 10:14:35 GMT
Content-Type: text/html

<html>
...
</html>

第一行称为status line,依次包括version、status code、reason phrase三个部分。

接下来也是若干行头字段。然后是一行空白。返回的HTML文本则附在空白行之后。

Node基础

学习Node,首先请参考Node.js官网进行安装。本书使用的是v6.4.0。安装完成后,命令行运行node --versionnpm --version,能得到正确的版本信息,表明安装成功。

新建app.js文件,写入如下内容:

var http = require('http');

function requestHandler(request, response) {
    // log
    console.log(request.method + ': ' + request.url);
    // actually handler the request
    response.end('Hello, Web!');
}

var server = http.createServer(requestHandler);

server.listen(3000);

这就是一个最简单的Node网络应用了。保存,然后进入命令行,运行:

$ node app.js

打开浏览器,访问http://localhost:3000,则会看到如下页面:

输入图片说明

而如果在地址栏输入http://localhost:3000/somewhere?p1=3&p2=4,依然会看到同样的内容:

输入图片说明

而命令行中则会出现如下的信息:

$ node app.js
GET: /
GET: /farvicon.ico
GET: /somewhere?p1=3&p2=4
GET: /farvicon.ico

上面的代码有如下值得注意的几点:

  1. 用到了Node的http内置模块
  2. 代码中的request实际上属于http模块的IncomingMessage“类”,对应前面提到的HTTP客服端请求:request.method对应请求行的第一部分,request.url则是请求行的第二部分,等等
  3. 相应地,response属于http模块的ServerResponse类,其end方法表示此次请求处理完毕,并向客户端回复相关的response信息
  4. http://localhost:3000实际上隐藏了/这个path,也就是说此时request.url的值是'/'

现在将requestHandler方程更改如下:

// in app.js
function requestHandler(request, response) {
    // log
    console.log(request.method + ': ' + request.url);
    // actually handler the request
    if (request.url === '/') {
        return response.end('Welcome to Homepage!');
    }
    if (request.url === '/about') {
        return response.end('Welcome to About Page!');
    }
    response.end('404, Page Not Found!');
}

运行程序,在地址栏输入不同的path,看看浏览器和命令行是否显示所预想的内容。

Http模块的不足

从上面的代码可以看出,用Node的http模块写成的服务器/网络应用,其组成和运行可以解析为下面这幅图:

输入图片说明

可以看出,图中黄色的部分,对应于代码中的requestHandler方法,这个需由应用的开发者提供的部分是服务器的核心,可以说整个服务器都是围绕这个方法建立的(var server = http.createServer(requestHandler))。Node的http模块收到来自客户端的HTTP请求后,会加以解析,创建分别对应请求和应答的对象作为参数传给处理request的方法。等该方法运行结束后,再利用更新后的应答对象,生成应答,回给客户端。

听起来非常简单,但是http模块的也有很严重的不足:

  1. 浏览其文档就可以发现,http模块的API非常简陋、功能也非常简单,要完成稍微复杂点的任务就会导致代码量猛增(比如实时渲染页面,或者当客户端向服务器请求的是静态文件时等等)
  2. 将所有处理请求的逻辑都写在一个方法里会导致应用极难扩展、不可维护

回想上一节中所提到的Express的优点,会发现Express正是意在解决这些不足。那么,它是如何做到的呢?

第一个不足好解决,Express就是Node之上再加的一片抽象层,它只需帮使用者处理好繁琐重复的任务、增强request和response等对象的功能、提供更好用的API即可。如下图:

输入图片说明

而第二个不足的解决才真正体现了Express的高明,也是其核心之处。最后提醒读者注意上图中的黄色部分已经从“处理request的方法”更名为了“处理request的逻辑”。其中的深意,留待以后的文章中说明。

转载于:https://my.oschina.net/qiaotoubao/blog/735374

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值