Express是一个极小而灵活的Node.js Web应用程序框架,为构建Web应用程序提供了一套强大的功能。
Express的官方网站是expressjs.com。 源可以在GitHub上找到。
入门
您将首先需要创建一个目录,在您的shell中访问它,并通过运行npm install express -save
,使用npm安装Express
创建一个文件并将其命名为app.js
,并添加以下代码,该代码创建一个新的Express服务器,并使用app.get
方法向其添加一个端点(/ ping
):
|
|
要运行您的脚本,请在您的shell中使用以下命令:
|
|
您的应用程序将接受本地主机端口8080上的连接。如果省略了app.listen
的hostname参数,则服务器将接受计算机的IP地址以及localhost上的连接。 如果端口值为0,则操作系统将分配可用端口。
一旦您的脚本运行,您可以在shell中测试它,以确认您从服务器获得预期响应“pong”:
|
|
您也可以打开一个Web浏览器,浏览到url http://localhost:8080/ping来查看输出
Basic routing
首先创建一个快速应用程序:
|
|
那么你可以定义这样的routes:
|
|
该结构适用于所有HTTP方法,并且期望path作为第一个参数,并且该路径的处理程序接收请求和响应对象。 所以,对于基本的HTTP方法,这些是routes
|
|
您可以在此处查看支持的verbs 的完整列表。 如果要为路由和所有HTTP方法定义相同的行为,可以使用:
|
|
or
|
|
or
|
|
您可以链接单个路径的路由定义
|
|
您还可以向任何HTTP方法添加功能。 它们将在最后回调之前运行,并将参数(req,res,next)作为参数。
|
|
您的最终回调可以存储在外部文件中,以避免将过多的代码放在一个文件中:
|
|
然后在包含您的routes的文件中:
|
|
这将使您的代码更整洁。
Modular express application
使快速Web应用模块化使用路由器工厂:
Module:
|
|
Application:
|
|
这将使您的应用程序模块化,可定制,您的代码可重用。
当访问http://<hostname>:8080/api/v1/greet
输出将是Hello world
比较复杂的例子
具有显示中间件工厂优势的服务的示例。
Module:
|
|
Application:
|
|
当访问http://<hostname>:8080/api/v1/service1/greet?name=World
时,输出将是Hello,World
并访问http://<hostname>:8080/api/v1/service2/greet?name=World
的输出将是Hello,World
。
使用模板引擎
使用模板引擎
以下代码将将Jade设置为模板引擎。
|
|
类似地,也可以使用其他模板引擎,例如Handlebars
(hbs
) 或ejs
。 记得要安装npm install
模板引擎。 对于Handlebars,我们使用hbs
包,对于Jade,我们有一个 jade
包,对于EJS,我们有一个ejs
包。 PS:Jade最近更名为pug
。
EJS模板示例
使用EJS(像其他快速模板),您可以运行服务器代码并从您的HTML访问您的服务器变量。
在EJS中,使用“<%
”作为开始标签,将“%>
”作为结束标签,可以使用<%=var_name%>
访问作为渲染参数传递的变量。
例如,如果您的服务器代码中有supplies array
你可以循环使用它
|
|
从示例中可以看出,每当您在服务器端代码和HTML之间切换时,都需要关闭当前的EJS标签,并在之后打开一个新的EJS标签,因此我们希望在for
命令中创建li
,因此我们需要关闭EJS标签 在最后,为大括号创建新标签
另一个例子
如果要将输入的默认版本从服务器端变为一个变量,我们使用<%=
例如:
|
|
这里从服务器端传递的消息变量将是您的输入的默认值,请注意,如果您没有从服务器端传递消息变量,EJS将抛出异常。 您可以使用res.render('index', {message: message});
传递参数(对于名为index.ejs的ejs文件)。
在EJS标签中,您还可以使用if
,while
或任何其他JavaScript命令。
提供静态文件
使用Express构建Web服务器时,通常需要提供动态内容和静态文件的组合。
例如,您可能将index.html和script.js作为文件系统中保留的静态文件。
通常使用名为“public”的文件夹具有静态文件。 在这种情况下,文件夹结构可能如下所示:
|
|
这是如何配置Express来提供静态文件:
|
|
注意:一旦文件夹被配置,index.html,script.js和“public”文件夹中的所有文件将在根路径中可用(您不能在url中指定/ public /
)。 这是因为,express快速查找相对于配置的静态文件夹的文件。 您可以指定虚拟路径前缀,如下所示:
|
|
将在/ static /
prefix下使资源可用。
多个文件夹
可以同时定义多个文件夹:
|
|
Express服务器将以定制顺序检查文件夹。 如果具有相同名称的文件,则第一个匹配文件夹中的文件将被提供。
添加中间件
中间件功能是可以访问请求对象(req),响应对象(res)以及应用程序的请求 - 响应周期中的下一个中间件函数的函数。
中间件功能可以执行任何代码,更改res和req对象,结束响应周期并调用下一个中间件。
中间件的很常见的例子是cors模块。 要添加CORS支持,只需安装它,就要求它并放置此行:
|
|
在任何路由器或路由功能之前。
Error Handling
Basic Error Handling
默认情况下,Express将在/views
目录中查找“error”视图来呈现。 只需创建“error”视图并将其放在视图目录中来处理错误。 使用错误消息,状态和堆栈跟踪写入错误,例如:
views/error.pug
|
|
Advanced Error Handling
在中间件功能堆栈的最后定义您的错误处理中间件功能。 这些有四个参数而不是三个(err,req,res,next)
,例如:
app.js
|
|
您可以定义几个错误处理中间件函数,就像常规中间件功能一样。
Express中的错误处理
在Express中,您可以定义统一的错误处理程序来处理应用程序中发生的错误。 在所有路由和逻辑代码的末尾定义处理程序。
例
|
|
从请求获取信息
从请求的URL获取信息(请注意,req
是路由的处理函数中的请求对象)。 考虑这个路由定义/settings/:user_id
和这个特定的例子/settings/32135?field=name
|
|
您也可以获取请求的标题,像这样
|
|
为了简化获取其他信息,您可以使用中间件。 例如,要获取请求的身体信息,您可以使用 body-parser 中间件,这将将原始请求体转换为可用格式。
|
|
现在假设这样的请求
|
|
您可以访问这样发布的名称
|
|
以类似的方式,您可以从请求访问Cookie,您还需要一个中间件,如 cookie-parser
|
|
Hook:如何在任何req之前和之后执行代码
app.use()
和中间件可以用于“before”,并且 close和 finish事件的组合可以用于“after”。
|
|
这个例子就是logger中间件,默认情况下它将追加到日志中。
只要确保这“中间件”是用在app.router
为顺序无关紧要。
具有ExpressJS的JSON API
|
|
在http://localhost:8080/
output对象上
|
|
在Express定制中间件
在Express中,您可以定义可用于检查请求或设置某些标题的中间件。
|
|
例
以下代码将user
添加到请求对象,并将控件传递给下一个匹配路由。
|
|
Named routes in Django-style
一个大问题是Express开箱即用不支持有valuable的命名路由。 解决方案是安装支持的第三方软件包,例如 express-reverse:
|
|
将其插入到您的项目中:
|
|
然后像这样使用它:
|
|
这种方法的缺点是您不能使用高级路由器使用中所示的路由Express模块。 解决方法是将您的app
作为参数传递给您的路由器工厂:
|
|
像这样使用:
|
|
您可以从现在开始,如何定义函数将其与指定的自定义命名空间合并并指向适当的控制器。
使用cookie-parser设置cookie
以下是使用 cookie-parser模块设置和读取Cookie的示例:
|
|
Error handling
基本文档可以在这里找到
|
|
Appendix A
|
|
Appendix B
|
|
处理POST请求
就像使用app.get
方法处理Express中的get请求一样,您可以使用app.post
方法来处理帖子请求。
但在您可以处理POST请求之前,您将需要使用body-parser中间件。 它只是解析POST
,PUT
,DELETE
和其他请求的正文。
Body-Parser
中间件解析请求的正文,并将其转换为req.body
中可用的对象
|
|
Hello World
在这里,我们使用Express创建一个基本的hello world服务器。路线:
- ‘/‘
- ‘/wiki’
rest 时会给出“404”,即找不到页面。
|
|
注意:我们将404路由作为最后一条路由,作为快速堆叠路由,并按顺序对每个请求进行处理。
使用中间件和next回调
Express将next
回调传递给每个路由处理程序和中间件功能,可用于跨多个处理程序的单个路由断开逻辑。 使用no参数调用next()
可以指示express继续下一个匹配的中间件或路由处理程序。 使用错误调用next(err)
将触发任何错误处理程序中间件。 调用next('route')
将绕过当前路由上的任何后续中间件,并跳转到下一个匹配路由。 这允许域逻辑被分离成可重复使用的组件,这些组件是独立的,更简单的测试,更易于维护和更改。
多个匹配路由
对/api/foo
或/api/bar
的请求将运行初始处理程序来查找成员,然后将控制权传递给每个路由的实际处理程序。
|
|
Error handler
错误处理程序是具有签名function(err, req, res, next)
的中间件。 它们可以按路径设置(例如app.get('/foo', function(err, req, res, next)
),但通常,呈现错误页面的单个错误处理程序就足够了。
|
|
中间件
上述每个功能实际上是一个中间件功能,只要请求与定义的路由匹配,就可以运行,但是可以在单个路由上定义任意数量的中间件功能。 这样就可以将中间件定义在单独的文件和常见逻辑中,以便跨多个路由重用。
|
|
在这个例子中,每一个中间件函数都可以是它自己的文件,也可以是文件中的其他变量,这样它可以在其他的路由中被重用。