Hello World
Express
是一个保持最小规模的灵活的 Node.js
Web
应用程序开发框架,为 Web
和移动应用程序提供一组强大的功能。
学习之前我们还是先看一个简单的demo
,运行一个hello world
程序。
打开终端输入以下命令
bash
$ mkdir dockerfile-test
$ cd dockerfile-test
$ yarn init -y
yarn init v1.22.18
warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications.
success Saved package.json
✨ Done in 0.02s.
$ mkdir src
$ mkdir public
$ cd src
$ touch server.js
$ cd ..
$ cd public
$ touch index.html
$ cd ..
$ yarn add express -S
到目前为止,我们就创建好了一个项目的基础目录,执行 tree -a
可以看到现在的目录如下
bash
├── package.json
├── public
│ └── index.html
└── src
└── server.js
接下来我们来填充下各个文件
html
// public/index.html
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
改造src/server.js
使用express
启动一个服务
js
// src/server.js
const express = require('express');
const { resolve } = require('path');
const server = express();
const port = parseInt(process.env.PORT || '8080');
const publicDir = resolve('public');
server.use(express.static(publicDir));
server.listen(port, () => console.log(`Listening on port ${port}`));
改造package.json
在 package.json
中设置启动脚本:
json
// package.json
{
"name": "dockerfile-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node src/server.js",
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.0.1"
}
}
启动服务yarn start
bash
$ yarn start
不出意外,打开http://localhost:8080
,你就能看见以下画面。
是不是很简单呢,没错这就是一个基础的express
的web
静态服务。
因为本文只是带大家了解一下一个项目初始阶段的入门知识,所以文本只介绍一些常用的入门模块,后续深入的部分请看我们看正文部分,会带大家手把手的去使用express
。
下面我们分四个部分去介绍下express
。其中 路由 分一个模块讲解、中间件,模板引擎 作为一个模块讲解、错误处理 会在搭建web
服务中作为独立模块讲解。
1. 路由
2. 中间件
3. 模板引擎
路由
路由是指确定应用程序如何响应客户端对特定端点的请求,端点是URI
(或路径)和特定的HTTP
请求方法(GET
、POST
等)。
每个路由可以有一个或多个处理程序函数,这些函数在路由匹配时执行。
为了能够实时的运行我们编写的程序,这里我们引入一个新的工具nodemon
。noodemon
是一个用于开发Node.js
应用程序的热重载工具。它的主要作用是在开发过程中监视文件的变化,当文件发生更改时,自动重启Node.js
应用程序,以便开发人员能够快速地看到代码修改的效果,而无需手动停止和重新启动应用程序。
bash
$ yarn add nodemon -S
我们在package.json
中配置启动命令
json
{
"name": "dockerfile-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node src/server.js",
+ "dev": "nodemon src/server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.0.1"
}
}
Route methods
路线定义格式:
demo
server.METHOD(PATH, HANDLER)
-
server
是express
的一个实例。 -
METHOD
是一个HTTP
请求方法,小写 -
PATH
是服务器上的路径。 -
HANDLER
是路由匹配时执行的函数。
示例:
在路由(/home
)上响应get
请求应用程序:
js
server.get('/home', function (req, res) {
res.send('Hello World!')
})
在路由(/home
)上响应POST
请求应用程序:
js
server.post('/home', function (req, res) {
res.send('Got a POST request')
})
响应对/user
路由的PUT
请求:
js
server.put('/user', function (req, res) {
res.send('Got a PUT request at /user')
})
响应对/user
路由的DELETE
请求:
js
server.delete('/user', function (req, res) {
res.send('Got a DELETE request at /user')
})
有一种特殊的路由方法,server.all()
用于在所有HTTP
请求方法的路径上加载中间件函数。例如,以下处理程序是为路由"/secret"的请求执行的,无论使用GET
、POST
、PUT
、DELETE
还是http
模块中支持的任何其他HTTP请求方法。
js
serve.all('/secret', function (req, res) {
res.send('Got a request at /secret')
})
将这些代码填充到server.js
文件中去。
js
// src/server.js
const express = require('express');
const { resolve } = require('path');
const server = express();
+ server.get('/home', function (req, res) {
+ res.send('Hello World!');
+ });
+ server.post('/home', function (req, res) {
+ res.send('Got a POST request');
+ });
+ server.put('/user', function (req, res) {
+ res.send('Got a PUT request at /user');
+ });
+ server.delete('/user', function (req, res) {
+ res.send('Got a DELETE request at /user');
+ });
+ server.all('/secret', function (req, res) {
+ res.send('Got a request at /secret')
+ })
const port = parseInt(process.env.PORT || '8080');
const publicDir = resolve('public');
server.use(express.static(publicDir));
server.listen(port, () => console.log(`Listening on port ${port}`));
使用yarn dev
执行命令。打开http://localhost:8080/home。我们能看到Hello World
字样,代表你/home
路由下的get
请求成功了,当然如果你想测试其他请求方法,建议下载一下postman
进行测试接口。
例如测试一下user
路由下的put
方法,我们可以这样。
postman
工具的使用因为不是我们的重点,我们这不做过多的介绍。感兴趣的同学可以查看官网。。
Route paths
路由路径与请求方法相结合,定义了可以发出请求的端点。路由路径可以是字符串、字符串模式或正则表达式。Express
使用path-to-regexp来匹配路由路径;我们还是来写一些demo来加深大家都路由的理解。
路由路径将匹配acd
和abcd
js
server.get('/ab?cd', function (req, res) {
res.send('ab?cd')
})
路由路径将匹配abcd
、abbcd
、abbbcd
javascript
app.get('/ab+cd', function (req, res) {
res.send('ab+cd')
})
路由路径将匹配abcd
、abxcd
、abRANDOMcd
、ab123cd
js
server.get('/ab*cd', function (req, res) {
res.send('ab*cd')
})
......
加入到server.js
使用postman
测试一下。下面其他的的大家可以自己去测试。了解了基本的方法建议大家可以学习一下path-to-regexp。
Route parameters
路由参数被命名为URL
段,用于捕获在URL
中的位置指定的值。捕获的值填充在req.params
对象中,路径中指定的路由参数的名称作为各自的键。示例格式:
demo
Route path: /users/:userId/books/:bookId
Request URL: http://localhost:8080/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }
要使用路由参数定义路由,只需在路由路径中指定路由参数,如下所示。
js
server.get('/users/:userId/books/:bookId', function (req, res) {
res.send(req.params)
})
注意:路由参数的名称必须由"单词字符"组成([A-Za-z0-9_]
)
高级用法 '-'
、'.'
demo
Route path: /flights/:from-:to
Request URL: http://localhost:8080/flights/LAX-SFO
req.params: { "from": "LAX", "to": "SFO" }
js
server.get('/flights/:from-:to', function (req, res) {
res.send(req.params)
})
demo
Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }
js
server.get('/plantae/:genus.:species', function (req, res) {
res.send(req.params)
})
demo
Route path: /user/:userId(\d+)
Request URL: http://localhost:3000/user/42
req.params: {"userId": "42"}
js
server.get('/user/:userId(\\d+)', function (req, res) {
res.send(req.params);
});
Route handlers
可以提供多个像中间件一样的回调函数来处理请求。
单个回调函数处理路由。例如:
js
server.get('/example/a', function (req, res) {
res.send('Hello from A!')
})
多个回调函数处理路由(请确保您指定next
对象)。例如:
js
server.get('/example/b', function (req, res, next) {
console.log('the response will be sent by the next function ...')
next()
}, function (req, res) {
res.send('Hello from B!')
})
响应体会返回Hello from B
,控制台会打印the response will be sent by the next function
...
回调函数数组处理路由
js
const cb0 = function (req, res, next) {
console.log('CB0')
next()
}
const cb1 = function (req, res, next) {
console.log('CB1')
next()
}
const cb2 = function (req, res) {
res.send('Hello from C!')
}
server.get('/example/c', [cb0, cb1, cb2])
响应体会返回Hello from C
,控制台会打印CB0
、CB1
...
Response methods
以下是 Express
框架中常用于响应对象(res
)上的方法,以表格形式列出:
方法 | 描述 |
---|---|
res.send([body]) |
发送 HTTP 响应。可以发送字符串、HTML 、JSON 对象等不同类型的响应内容。 |
res.json([body]) |
发送 JSON 格式的响应。通常用于发送包含数据的 JSON 响应。 |
res.render(view, [locals]) |
渲染视图模板并发送 HTML 响应。通常与模板引擎一起使用,将数据注入视图模板生成 HTML 页面。 |
res.redirect([status,] path) |
重定向客户端到指定路径。可以指定重定向的状态码,默认为 302 (临时重定向)。 |
res.status(code) |
设置 HTTP 响应的状态码。通常用于指定响应状态,如 200 (成功)或 404 (未找到)。 |
res.setHeader(name, value) |
设置响应头部的字段和值。可以用于自定义响应头部信息。 |
res.cookie(name, value, [options]) |
设置 HTTP 响应中的 cookie 。允许在客户端存储数据,通常用于会话管理和用户身份验证。 |
res.clearCookie(name, [options]) |
清除 HTTP 响应中的 cookie 。通常用于注销用户或删除存储在客户端的数据。 |
res.attachment([filename]) |
设置响应的 "Content-Disposition " 头部,使得浏览器提示下载文件。 |
res.set(field, [value]) |
设置响应头部的字段和值。类似于 res.setHeader ,用于自定义响应头部信息。 |
res.type(type) |
设置响应的 "Content-Type " 头部,指定响应的 MIME 类型。 |
res.locals |
一个包含了响应局部变量的对象。通常用于在中间件中传递数据给视图渲染。 |
res.sendfile(path, [options], [callback]) |
以流的形式发送文件作为响应内容。通常用于提供文件下载或静态文件服务。 |
这些方法允许你以不同的方式构建和发送 HTTP
响应,根据需要设置状态码、响应头、响应体等内容。 Express
提供了丰富的工具和方法,以便于构建各种类型的 Web
应用程序。
server.route()
您可以使用app.route()
为路由路径创建可链接的路由处理程序
js
server.route('/book')
.get(function (req, res) {
res.send('Get a random book')
})
.post(function (req, res) {
res.send('Add a book')
})
.put(function (req, res) {
res.send('Update the book')
})
Express Router
Router
实例是一个完整的中间件和路由系统,我们结合下一个模块中间件进行讲解。
总结
本文主要是进行了项目的初始搭建和基于express
的路由系统讲解,Express.js
的路由模块是构建 Web
应用程序时非常重要的一部分。它负责将客户端请求映射到相应的处理程序函数,从而实现不同 URL
路径的不同行为。
一个来自底层的小白程序员,希望大家多多点赞 、收藏 、关注,你的鼓励是我前进的动力,谢谢大家。