学习一门新的知识,首先要对这个知识有个正确的认知。所以我们学习express之前先来了解下express是什么东西,是干什么的。
以下内容来源于官网:
基于 Node.js 平台,快速、开放、极简的 Web 开发框架
Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能。
express是基于Node.js平台的,是一个Web开发框架。
首先我们在了解Node.js时,大部分人应该都遇到过同样的东西,那就是创建HTTP服务,这个HTTP服务能够在浏览器上去访问,同时能够接受各种http请求。而我个人认为,express就是丰富了内容,能够创建更加规范化使用的HTTP服务的一个框架。
基于此认知,我们来开始使用express。
首先是express的下载,这里区别于是否将express添加到依赖列表中,来用npm执行以下命令
添加到依赖列表
$ npm install express --save
不添加到依赖列表
$ npm install express --no-save
安装好express后,我们现在命令窗口看下express的使用,输入express -h的指令来查看express的用法
基础用法为:express [可选项] [文件名]
其中可选项可省略,文件名不可省略,输入指令后express将会根据模板创建一个以指定文件名命名的文件夹,里面带有创建好的应用文件。
(不重要部分:
下面的内容分别是
--version 查看express版本
--ejs 添加ejs引擎支持
--pug 添加pug引擎支持
--hbs 添加hbs引擎支持
--hogan 添加对hogan.js的支持
--view <engine> 用 --view <引擎名称>来添加指定引擎的支持,默认为jade引擎支持
--no-view 不使用其他引擎支持
--css <engine> 用--css <指定类型>来添加指定类型的样式支持,默认为css
--git 添加git文件忽视的规则
--force 暂且不知(抹汗)
--help 查看express帮助
前面单横杆是同行指令的简写
)
我们以app来命名创建一个应用文件夹,在命令窗口输入express app的指令,此时会创建一个app文件夹,文件结构如图所示。
其中有9个文件和7个文件夹。
我们从这个模板来理清一下这个应用是如何启动的。
通过查看package.json得知入口文件是bin文件夹下的www这个文件。我们打开这个文件,合并所有代码后发现里面的内容其实和node.js创建http服务很像,本质上是一样引入http,通过http以引入的app为对象来创建服务并设置好监听端口,同时为这个服务添加了一些自定义方法来处理一些情况。
而后我们来看下引入的app是什么。
app来源于app.js,app.js导出一个app对象,在这个文件里app是通过引入的express模块创建的app对象,这个app.js文件同时对routes里的两个文件进行引用,我们可以通过命名得知这两个文件设置的都是路由对象,而打开这两个文件,我们就会发现,这里其实是对一些路由的请求的设置。也就是说,这个应用是通过express创建的app对象来管理http服务,而这个app对象可以通过引入对不同路由的设置来处理对相应路由收到的各种请求。
接下来我们来了解下express的用法。
首先是路由
发起的请求分为两个概念,一个是请求方式,一个是请求地址,请求地址分为域名(ip地址+端口号)+地址,后面这个地址正是我们所说的路由。
express创建的app对象对请求的处理有很多方法,如针对性较强的有
app.get('/', (req, res) => res.send())
这里以这个例子为例,app有get方法来处理get请求,第一个参数就是路由,后面可以添加对这个请求的处理方法,其中req(request)和res(response)与node.js提供的相同,并且以res.send()方法来响应请求方(需注意的是res.send()方法里可提供参数,并且这个方法会以提供内容的相同格式发送给请求方,这个可以在app.js的全局设置来统一处理)。同理,app还有post、put、delete等不同请求。用法一样。
同时app也有app.route()来统一处理一个路由
app.route('/animal')
.get( (req, res) => res.send())
.post( (req, res) => res.send())
.put( (req, res) => res.send())
.delete( (req, res) => res.send())
app还有app.all()来对相同路由的所有请求统一处理
app.all('/plant', (req, res) => res.send())
此外,express还支持对路由的智能匹配和模糊处理。
在路由这个参数上可以添加一下内容来匹配相应的路由
'/abc+xyz/home' 这个可以匹配'/abcxyz/home'和'/abccccccccccxyz/home'等诸如此类,其中的加号可替换成任意的小写字母组合
'/ab*yz/home' 这个可以匹配'/abyz/home'和'/abbB51ddyz/home'等诸如此类,其中的加号可替换成任意的大小写字母和数字组合
'/ab(gg)?yz/home' 这个只能匹配'/abyz/home'和'/abggyz/home'两个路由
/abc/ 这个参数没有引号,能匹配所有带有'abc'组合的路由,这个组合可以是单个字母或者数字(未测试)
/.*xyz/ 这个参数没有引号,能匹配所有以'xyz'组合结尾的路由(未测试,未知是否能匹配'/abxyz/home')
'/user/:userId/hobby/:hobbyId' 这个参数里带有冒号的可以匹配任意的值,并且可以通过req.params在后续的处理方法中提取出来使用。如
Route path: /users/:userId/books/:bookId
Request URL: http://localhost:3000/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }
为了便于处理请求,express还添加了中间件的概念,按照我的理解就是在res.send()之前,可以添加多个处理函数来方便分步处理请求
app.get('/data', (req, res, next) => {
// 此处执行步骤一
...
next()
}, (req, res, next) => {
// 此处执行步骤二
...
next()
}, (req, res) => {
// 此处执行步骤三
...
res.send()
}
在res.send()的方法之前可以添加多个参数带有req, res, next的方法用作中间处理(如果参数有next,则必须执行next()才会向下执行,否则请求将会停留在此处被挂起,不再执行后续的方法),这有益于分步骤处理请求。
express还可以托管指定目录的文件
express.static(root, [options])
root是指文件目录,options是指可选项。这样express就对指定文件目录下的文件开放了访问权限,我们就可以通过请求去访问内部的文件了。
为了区别于其他请求,我们可以为访问文件的请求添加一个指定的前缀
app.use('/static', express.static('public'))
这样就可以通过带有'/static'前缀的路由来区分是不是请求静态文件
如访问public文件夹下的css文件夹的reset.css这个文件,就通过请求'/static/css/reset.css'来访问指定文件。
express的基本功能的学习就到此结束了,express的更多应用还要配合其他的模块来一起使用,搭配中间件,能够更好地处理各种请求,同时也可以通过各种模块来补充express创建的应用的功能,如NoSQL数据库之类的。
最后声明一下,这篇文章有很多内容是基于个人对express的理解,难免可能有错的地方。如果看到这里,您觉得有所帮助的话,不妨点个赞吧。