我们之前直接通过node.js创建web十分麻烦,通过express可以进行简化,本篇主要介绍express内容:
1、express概念
Express是一个基于Node平台的web应用开发框架,其提供了一系列的强大特性,帮助开发者方便的创建各种web应用;
其使用必须通过npm install express进行下载;
其主要特点如下:
1、比如前面用到的router就是这里提取出去的
2、请求参数不再需要经过复杂的处理,直接拿到的就是对象(以前要经过data、end事件)
3、中间件可以如拦截请求等等,让效果更多
下面将请求参数获取进行对比两者的简便性,原始node.js如下:
需要进行拼接且还需要进行querystring转成对象,而express中则简单:
2 express示例
通过express模块创建服务器如下所示:
可以看到只要执行express()即可以创建一个服务器,此外其用的是send方法,会自动帮我们设置好content-type,这是在原始node中需要我们手动设置的,send还会自动设置http的响应码;
3 express中间件
中间件是一堆方法,可以接受客户端发来的请求,对请求作出相应,或将请求交给下一个中间件处理,如之前的get,post方法就是中间件;
如上图,中间件在接受到请求时,可以自己进行处理,处理完后还可以根据实际需求决定是否交给下一个中间件;
详细介绍:
对于同一个请求可以设置多个中间件,默认由上到下进行匹配,如果匹配成功就不会再继续向下匹配,如果还想继续向下匹配则必须通过next方法将控制权交给下一个中间件:next要写在回调函数参数及函数体中:
app.use中间件:其也是用于接收请求的,但是相比于上面的post与get,其不再进行区分请求方式,如下只要地址是/request就会触发,不管请求方式,如果地址为空则每一个请求都会触发:
中间件的使用:
1、路由保护,客户端在访问需要登录的页面时,可以先用中间件判断用户的登录状态,用户如果未登录则拦截该请求,禁止用户进入需要登录后才有权限的页面:
上面是如果已经登录就通过next将权限给下一个中间件去响应请求,如果没有登录直接在当前中间件中进行响应拒绝访问;
2、网站维护公告,在所有路由最上面定义接收所有请求的中间件,一律返回网站维护的公告:
3、自定义404公告,当用户请求的页面不存在时,可以返回404页面,该中间件应该写在最后面(因为前面的都没有的话,则表明没有该页面存在):
但此时打开资源管理器发现返回的还是200状态码,需要对齐进行更改,下面将其设置成了404:
处理错误的中间件:
在程序执行过程中,不可避免会出现一些无法预料的错误,比如文件读取失败,数据库连接失败…错误处理中间件是一个集合处理错误的地方,避免错误影响程序向下继续执行:
其就是use回调函数加了第一个参数err,其在出错时自动调用该中间件,err会自动变成当前错误,具体案例如下:
这里先是通过new了一个Error的实例对象,其就是个错误,然后通过throw将其抛出,下面的错误处理中间件则会自动执行,向客户端send会错误信息;
但注意上面的写法只能对于同步代码中的错误,对于异步错误,需要进行手动调用错误处理中间件,在调用next()时给其参数(不传参数时表示将控制权给下一个中间件,传参表示触发错误处理中间件):
这里判断err是否不为空,如果不为空即异步读取文档出错了,通过next(err)调用错误处理中间件;
捕获错误:
如下代码所示:
将可能出错的代码放在try中,如果不出错其会跳过后面的catch执行后面的其他代码,如果出错了则会调用catch(其参数就是捕获的错误信息)中的next去调用错误处理中间件;
3 构建模块化路由
上面的路由都是在同一个文件中,但在项目中,页面十分多,都放在同一个文件下会产生混乱,所以将不同模块的路由放在不同文件中方便管理,且express提供了创建路由的方法Router:
之前的use第二个参数都是回调函数,而这里是个路由对象(这是一级路由,具体操作在二级路由中实现)下面的get中就是二级路由,则这样访问的是/home/index地址就会返回相应的信息;
多个路由文件时:
在主文件app.js中引入了两个路由文件,在主文件中写一级路由,二级路由在下面的路由文件中写;
get参数的获取:
由上面我们可以看到通过req.query获取get请求参数,其自动转为了对象:
post参数的获取:
post的获取参数方法也是express推出的,但是为了让体积减小没有包含,要使用必须进行npm install:
其中先通过use拦截所有请求,调用bodyParser对参数进行处理后其会自动next移交权限,下面的post就可以处理,而这时打印req.body就已经是处理好的对象数据了;
其中的extended参数为false时使用querystring进行处理,为true时使用qs第三方模块对请求参数进行处理(且比querystring更强大);
除了上面的方式外,还可以通过express路由参数获取,其路由如下:
则在访问该页面时必须:
这里123就是上面的id值,如果不写后面的123则无法进入该页面,然后在服务端通过params进行获取即可;
如果想要传多个参数,则:
在访问时写:
express静态资源访问:
前面访问静态资源要借用第三方模块,在express中使用express.static可以方便地静态托管文件(静态资源一般放在public文件夹下)(如:一些不会变的html、css、图片等等…):
其会自动判断请求的是否是静态资源,如果是就直接返回相应资源,如果不是则会自动调用方法中的next()将控制权交给下一个中间件;
通过其可以访问public文件夹下的内容了:
4 模板引擎
在这里模板语法与之前相同,仅是配置有所不同而已:
注意这里的views与view engine都是固定用于设定相应内容的;
这里只要将render中传入index模板,会自动将其中msg替换为‘message’;
在不同页面中通常会有公共部分,如果这部分数据每次都从写一次,通过将变量写给app.locals对象,在所有模板中都可以使用:
其在所有模板中都可以使用(用render只能是针对当时路由传递的模板):