Express中间件:完整指南

2020年12月30日11:13:45 发表评论 33 次浏览

本文概述

在本指南中, 我们将探讨使用Express.js中间件的基础知识。我们将从头开始创建一个简单的Express API, 然后将中间件添加到其中, 并演示如何使用每种工具。

我们将要讨论的Express中间件工具是Express.js应用程序初始设置的必备条件。我们将向你展示如何开始使用它们, 并且你可以根据应用程序的独特需求对其进行进一步配置。

我们将介绍以下内容:

  • 什么是Node.js?
  • 什么是Express.js?
  • 什么是Express中间件?
  • 中间件如何工作?
  • 设置Express.js API
  • 使用Express中间件
    • 摩根
    • 头盔
    • 科尔斯
    • 快递费限制
    • 服务图标

为简单起见, 我们将在示例Express API中仅创建一个端点。完整的代码可在的GitHub.

什么是Node.js?

Node.js是一个基于Java的开源JavaScript运行时环境Chrome的V8 JavaScript引擎.

尽管Node.js可以处理诸如创建简单服务器之类的基本任务, 但更复杂的任务(如分别处理不同路径的请求或提供静态文件)则更加困难。

什么是Express.js?

Express.js是最流行且使用最广泛的Node Web框架之一。实际上, MERN, MEVN和MEAN Stack中的" E"代表" Express"。

据官方介绍Express.js文档, " Express是一个用于Node.js的快速, 不受限制的极简网络框架。"尽管Express是极简主义的, 但是它也非常灵活, 这导致了各种中间件的开发, 这些中间件可与Express.js一起使用, 以解决几乎所有你能想到的任务或问题。

什么是Express中间件?

中间件是包含在请求-响应周期内执行的功能并且可以访问请求对象(req)和响应对象(res)的功能的软件。在服务器接收请求和发送响应之间的窗口期间执行中间件。

快速中间件包括应用程序级, 路由器级和错误处理功能, 可以是内置的或来自第三方的。由于Express.js自身的功能有限, 因此Express应用程序主要由多个中间件函数调用组成。

我们为制作了一个自定义演示.
不完全是。点击这里查看.

Express中间件:完整指南1

你可以为Express.js编写自己的中间件, 但是大多数开发人员更喜欢使用和配置内置工具和第三方工具来完成常见任务。在本指南中, 我们将向你展示如何使用五个最受欢迎的Express中间件。但首先, 简短概述一下中间件如何在应用程序中运行。

中间件如何工作?

要了解中间件的工作原理, 请想象你拥有一个柠檬水摊, 顾客可以自己带柠檬, 然后制作柠檬水。你有责任评估柠檬的来源和新鲜度, 丢弃任何不合格的柠檬, 最后制作柠檬水。

为了减少工作量, 你雇用了一个工人(我们称为Larry)来确保柠檬是有机种植的, 并且没有任何有害化学物质。以此类推, Larry是在你和客户的柠檬之间起作用的中间件。

现在你开始获利, 因此你又聘请了另外两名员工Curly和Moe。拉里(Larry)检查了柠檬的来源, 然后将有机种植的柠檬传递给柯利(Curly), 后者将烂柠檬丢弃, 然后将优质柠檬交给萌(Moe)。 Moe会验证其新鲜度, 并将新鲜的柠檬交给你。

现在, 你可以专注于制作柠檬水和增加利润。

将柠檬视为HTTP请求, 并将柠檬水视为服务器。你可以像接受HTTP请求一样检查柠檬的来源, 然后再接受或拒绝。并非所有来自受信任来源的请求都是好的, 因此仍然需要对其进行过滤。你的员工-Larry, Curly和Moe-就像你的柠檬水计划的中间件。如果中间件在任何阶段都确定请求是错误的, 则它可以终止请求-响应周期。

一旦请求通过了应用程序中存在的所有中间件, 它就会到达控制器功能-在我们的示例中, 就是你(或者更具体地说, 是制作柠檬水的行为)。

中间件的视觉解释

显然, 这只是一个简单的例子。在实际情况中, 你可能需要使用多个中间件来执行单个任务, 例如记录用户。

设置Express.js API

为了演示如何使用Express.js中间件, 我们将创建一个简单的Express API具有单个端点。

在终端中运行以下命令:

mkdir express-api
cd express-api
npm init -y

最后一条命令将创建一个package.json文件放在你项目的根目录中。它看起来像这样:

{
"name": "express-api", "version": "1.0.0", "description": "", "main": "index.js", "scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}, "keywords": [], "author": "", "license": "MIT"
}

运行以下命令进行安装表现:

npm install express

创建一个名为index.js:

touch index.js

将以下内容添加到index.js创建一个简单的Express API:

const express = require("express");
const app = express();

// Port
const port = 3000;

app.get("/", (req, res) => {
  res.json({
    message: "Hello Stranger! How are you?", });
});

// Listen
app.listen(port, () => {
  console.log(`Listening on port: ${port}`);
});

在项目的根目录中运行以下命令进行安装Nodemon作为开发人员的依赖。这是一个出色的本地开发工具。

npm install -D nodemon

用Nodemon, 则不必手动重新启动Express.js服务器;Nodemon检测文件更改并自动重新启动服务器。

修改"脚本"在你的package.json, 像这样:

"scripts": {
    "start": "node index.js", "dev": "nodemon index.js"
  }, 

你的package.json应该看起来像这样:

{
  "name": "express-api", "version": "1.0.0", "description": "", "main": "index.js", "scripts": {
    "start": "node index.js", "dev": "nodemon index.js"
  }, "keywords": [], "author": "Ashutosh K Singh", "license": "MIT", "dependencies": {
    "express": "^4.17.1"
  }, "devDependencies": {
    "nodemon": "^2.0.6"
  }
}

运行以下命令以启动Express服务器:

npm run dev

服务器启动后, 你将在终端中看到以下消息:

[nodemon] 2.0.5
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js, mjs, json
[nodemon] starting `node index.js`
Listening on port: 3000

前往http://本地主机:3000并且你会从API中看到以下响应:

{
  "message": "Hello Stranger! How are you?"
}

使用Express中间件

现在, 我们已经设置了一个简单的API, 让我们详细了解五个顶级Express.js中间件工具以及如何使用它们。我们将描述每个中间件, 它的功能以及如何通过我们的Express API设置和使用它。

摩根

摩根是Node.js的HTTP请求记录器中间件, 可为每个API请求生成日志。最好的部分是你可以使用预定义的格式, 也可以根据需要创建新的格式。

安装摩根, 运行以下命令:

npm install morgan

摩根包含许多可以使用的预定义格式。许多开发人员更喜欢使用共同, 这是标准的Apache通用日志输出。

修改你的index.js像这样:

const express = require("express");
const morgan = require("morgan")

const app = express();

// Middlewares
app.use(morgan("common"))


// Port
const port = 3000;

app.get("/", (req, res) => {
  res.json({
    message: "Hello Stranger! How are you?", });
});

// Listen
app.listen(port, ()=>{
    console.log(`Listening on port: ${port}`)
})

完成了!前往http://本地主机:3000, 你会看到类似这样的日志, 由摩根在运行服务器的终端中:

::ffff:127.0.0.1 - - [14/Oct/2020:09:21:16 +0000] "GET / HTTP/1.1" 304 -

这是相同的屏幕截图:

摩根日志

请务必注意, 中间件工具是按照定义它们的顺序执行的。

头盔

头盔是一种安全中间件, 它通过设置各种HTTP标头来保护Express.js应用程序。

为了更好的理解头盔如何工作, 前往http://本地主机:3000 /然后按以下方式打开控制台Ctrl + Shift + J在Chrome或Ctrl + Shift + K在Firefox中。现在点击网络标签。

网络标签

如果网络标签为空, 请使用网络标签打开, 你会看到其中充满了条目。

网络标签填满

你可以忽略网站图标现在请求;我们稍后再讲。

点击GET /请求数据。专注于响应标题部分。

响应标题下拉菜单

你可能没有看到任何漏洞, 但是, 由于你的API目前存在, 攻击者和黑客可以轻松利用它-特别是X-Powered-By:快递字段, 向世界广播该应用程序正在运行Express.js。

头盔是11种小型中间件共同保护你的应用程序免受众所周知的漏洞和攻击。

运行以下命令进行安装头盔:

npm install --save helmet

更新index.js这样的文件包括头盔中间件:

const express = require("express");
const morgan = require("morgan")
const helmet = require("helmet");
const app = express();


// Middlewares
app.use(morgan("common"))
app.use(helmet());
// Port
const port = 3000;

app.get("/", (req, res) => {
  res.json({
    message: "Hello Stranger! How are you?", });
});
// Listen
app.listen(port, () => {
  console.log(`Listening on port: ${port}`);
});

再次前往http://本地主机:3000 /, 刷新页面, 然后打开响应标题下的部分网络签入开发者工具.

“网络”选项卡下的响应标题

如你所见, 这次有新项目响应标题和X-Powered-By:快递场不见了。

你还可以配置头盔()函数来禁用这样的中间件。

// This disables the `referrerPolicy` middleware but keeps the rest.
app.use(
    helmet({
        referrerPolicy: false, })
  );

科尔斯

CORS代表跨域资源共享。它用于在Express.js应用程序中启用和配置CORS。

假设你有一个全栈应用程序, 其中一个React前端运行在端口3000上, 一个Express后端服务器运行在端口8000上。请求从客户端(即React前端)发送到后端Express服务器, 但是你的请求将大部分可能会失败, 因为它来自与Express服务器不同的来源。

Cors错误

你需要告诉服务器接受此请求, 即使该请求来自其他来源。那边科尔斯进来。

运行以下命令进行安装科尔斯:

npm install --save cors

更新index.js像这样:

const express = require("express");
const morgan = require("morgan")
const helmet = require("helmet");
const cors = require("cors");
const app = express();


// Middlewares
app.use(morgan("common"))
app.use(helmet());
app.use(cors())

// Port
const port = 3000;

app.get("/", (req, res) => {
  res.json({
    message: "Hello Stranger! How are you?", });
});
// Listen
app.listen(port, () => {
  console.log(`Listening on port: ${port}`);
});

上面的代码app.use(cors())允许来自任何来源的请求, 但这可以使你的应用程序面临安全漏洞, 除非你拥有要接受来自任何来源的请求的公共API。

让我们考虑上面带有React和Express的全栈应用示例。你可以创建允许域的白名单, 然后检查请求是否来自白名单域, 而不是允许来自任何源的请求。

// whitelist
const whitelist = ['http://localhost:3000', 'http://localhost:3001']
const corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}
app.use(cors(corsOptions));
现在显示为列入白名单的域

你可以在上阅读有关CORS的更多信息MDN网站文档.

快递费限制

快递费限制是Express.js的基本限速中间件, 顾名思义, 该中间件限制了来自同一IP地址的重复API请求。

安装方法如下限速:

npm install --save express-rate-limit

接下来, 将该中间件导入到index.js并创建一个名为限制器配置限速.

const rateLimit = require("express-rate-limit");

const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100 // limit each IP to 100 requests per windowMs
  });

上面的代码在15分钟的时间内将每个IP地址限制为100个请求。

更新index.js像这样:

const express = require("express");
const morgan = require("morgan")
const helmet = require("helmet");
const cors = require("cors");
const rateLimit = require("express-rate-limit");

const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100 // limit each IP to 100 requests per windowMs
  });

const app = express();


// Middlewares
app.use(morgan("common"))
app.use(helmet());
app.use(cors())
app.use(limiter); //  apply to all requests

// Port
const port = 3000;

app.get("/", (req, res) => {
  res.json({
    message: "Hello Stranger! How are you?", });
});
// Listen
app.listen(port, () => {
  console.log(`Listening on port: ${port}`);
});

为了更好地展示如何使用限速, 更改限制, 像这样:

const limiter = rateLimit({
    windowMs: 60 * 1000, // 1 minute
    max: 2, // limit each IP to 2 requests per windowMs
    message: "Too many accounts created from this IP, please try again after a minute"
  });

前往http://本地主机:3000 /并刷新页面三到四次。

多次刷新页面

以来摩根仍然有效, 你可以在终端中查看日志。

::1 - - [14/Nov/2020:08:15:58 +0000] "GET / HTTP/1.1" 304 -
::1 - - [14/Nov/2020:08:15:59 +0000] "GET / HTTP/1.1" 304 -
::1 - - [14/Nov/2020:08:15:59 +0000] "GET / HTTP/1.1" 429 71

的429状态码表示用户在给定的时间内发送了太多请求("速率限制")。

你还可以配置限速适用于特定请求或并非所有请求。

//  apply to all requests
app.use(limiter); 

// only apply to requests that begin with /api/
app.use("/api/", limiter);

以下是一些值得一试的限速中间件:

  • 限速灵活
  • 蛮横的
  • 限速器

服务图标

服务图标是提供服务的中间件图标。你可能还记得我们打开网络标签在"头盔"部分。

Favicon请求失败

一种F航空兵是一个小图标, 通常出现在地址栏中页面标题的左侧。例如, 以下是notlogy博客的收藏夹图标:

Logrocket Favicon

安装服务图标:

npm install serve-favicon

你还需要在项目的根目录中添加一个收藏夹文件。你可以从以下位置获取示例收藏夹图标的GitHub.

更新index.js像这样的文件:

const express = require("express");
const morgan = require("morgan")
const helmet = require("helmet");
const cors = require("cors");
const rateLimit = require("express-rate-limit");
var favicon = require('serve-favicon')


const limiter = rateLimit({
    windowMs: 15 *60 * 1000, // 15 minutes
    max: 100, // limit each IP to 100 requests per windowMs
    message: "Too many accounts created from this IP, please try again after a minute"
  });

const app = express();

// Serve Favicon
app.use(favicon('favicon.ico'))

// Middlewares
app.use(morgan("common"))
app.use(helmet());
app.use(cors())
app.use(limiter); //  apply to all requests

// Port
const port = 3000;

app.get("/", (req, res) => {
  res.json({
    message: "Hello Stranger! How are you?", });
});
// Listen
app.listen(port, () => {
  console.log(`Listening on port: ${port}`);
});

如果你的网站图示存在public文件夹, 你可以使用路径.

var path = require('path')
 ...

// Serve Favicon
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))
...

前往http://本地主机:3000 /;你会看到页面上显示一个收藏夹图标。

显示网站图标的位置

现在打开网络标签并重新加载页面。

刷新的网络页面,显示网站图标

服务图标它还将favicon缓存在内存中, 以通过减少磁盘访问来提高性能。

默认, 服务图标将图标保存一年。

Cache-Control: public, max-age=31536000

你也可以改变缓存控制通过传递具有以下属性的选项对象最大年龄in网站图标.

// Serve Favicon
app.use(
  favicon("favicon.ico", {
    maxAge: 500 * 60 * 60 * 24 * 1000, })
);

总结

在本文中, 我们讨论了如何使用五个Express.js中间件。当然, 你可能想要探索Express API的其他中间件, 但是我们在本指南中检查的工具几乎可以在任何应用程序中使用, 并提供Express中间件可以用来增强API的出色快照。

只有200 监视生产中失败和缓慢的网络请求

部署基于节点的Web应用程序或网站很容易。确保你的Node实例继续为你的应用程序提供资源是一件很困难的事情。如果你希望确保成功完成对后端或第三方服务的请求,

尝试notlogy

.

LogRocket网络请求监控

https://notlogy.com/signup/

日志火箭就像Web应用程序的DVR一样, 实际上记录了你网站上发生的一切。无需猜测问题发生的原因, 你可以汇总并报告有问题的网络请求, 以快速了解根本原因。

notlogy用你的应用程序记录基线性能计时, 例如页面加载时间, 到第一个字节的时间, 缓慢的网络请求, 并记录Redux, NgRx和Vuex的操作/状态。

免费开始监控

.

一盏木

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: