从零搭建 Node.js+NextJs企业级 Web 服务器(二):项目基础知识之Express路由模块

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.jsonpackage.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,你就能看见以下画面。

是不是很简单呢,没错这就是一个基础的expressweb静态服务。

因为本文只是带大家了解一下一个项目初始阶段的入门知识,所以文本只介绍一些常用的入门模块,后续深入的部分请看我们看正文部分,会带大家手把手的去使用express

下面我们分四个部分去介绍下express。其中 路由 分一个模块讲解、中间件,模板引擎 作为一个模块讲解、错误处理 会在搭建web服务中作为独立模块讲解。

1. 路由

2. 中间件

3. 模板引擎

路由

路由是指确定应用程序如何响应客户端对特定端点的请求,端点是URI(或路径)和特定的HTTP请求方法(GETPOST等)。

每个路由可以有一个或多个处理程序函数,这些函数在路由匹配时执行。

为了能够实时的运行我们编写的程序,这里我们引入一个新的工具nodemonnoodemon是一个用于开发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)
  1. serverexpress的一个实例。

  2. METHOD是一个HTTP请求方法,小写

  3. PATH是服务器上的路径。

  4. 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"的请求执行的,无论使用GETPOSTPUTDELETE还是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来加深大家都路由的理解。

路由路径将匹配acdabcd

js 复制代码
server.get('/ab?cd', function (req, res) {
    res.send('ab?cd')
})

路由路径将匹配abcdabbcdabbbcd

javascript 复制代码
app.get('/ab+cd', function (req, res) {
  res.send('ab+cd')
})

路由路径将匹配abcdabxcdabRANDOMcdab123cd

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,控制台会打印CB0CB1 ...

Response methods

以下是 Express 框架中常用于响应对象(res)上的方法,以表格形式列出:

方法 描述
res.send([body]) 发送 HTTP 响应。可以发送字符串、HTMLJSON 对象等不同类型的响应内容。
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 路径的不同行为。

一个来自底层的小白程序员,希望大家多多点赞收藏关注,你的鼓励是我前进的动力,谢谢大家。

完整代码

github地址

参考资料

相关推荐
广煜永不挂科23 分钟前
Devexpress.Dashboard的调用二义性
c#·express
GISer_Jing3 小时前
React核心功能详解(一)
前端·react.js·前端框架
星星会笑滴5 小时前
vue+node+Express+xlsx+emements-plus实现导入excel,并且将数据保存到数据库
vue.js·excel·express
鑫宝Code7 小时前
【React】React Router:深入理解前端路由的工作原理
前端·react.js·前端框架
沉默璇年16 小时前
react中useMemo的使用场景
前端·react.js·前端框架
2401_8827275716 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
红绿鲤鱼17 小时前
React-自定义Hook与逻辑共享
前端·react.js·前端框架
zhenryx20 小时前
前端-react(class组件和Hooks)
前端·react.js·前端框架
Thomas游戏开发21 小时前
Unity3D 逻辑服的Entity, ComponentData与System划分详解
前端框架·unity3d·游戏开发
远之喵21 小时前
@tinyhttp/app VS express
express