https://express.js.cn/

核心包

  • npm install express 即可实现对应的安装实现吧

入门的学习

编写第一个 api

const express = require('express');

const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
    res.send('hello world');
})

app.listen(PORT, () => {
    console.log('server is running', `http://localhost/${PORT}`);
})
  • 核心定义后端路由的实现就是基于我们的: 正则表达式来实现动态的匹配吧,从而实现对应的操作讷,这个是 URI 的概念吧

路由(Routing)是指应用程序的端点(URI)如何响应客户端请求

路由方法指定了一个回调函数(有时称为“处理函数”),当应用程序接收到对指定路由(端点)和 HTTP 方法的请求时,会调用该函数。换句话说,应用程序“侦听”与指定路由和方法匹配的请求,当检测到匹配时,它会调用指定的回调函数

有一个特殊的路由方法 app.all(),用于在某个路径上为所有 HTTP 请求方法加载中间件函数。例如,以下处理程序将为路由 "/secret" 的请求执行,无论使用的是 GETPOSTPUTDELETE,还是 http 模块中支持的任何其他 HTTP 请求方法

中间件

const express = require('express')
const app = express()

const myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

app.use(myLogger)

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(3000)
const express = require('express')
const cookieParser = require('cookie-parser')
const cookieValidator = require('./cookieValidator')

const app = express()

async function validateCookies (req, res, next) {
  await cookieValidator(req.cookies)
  next()
}

app.use(cookieParser())

app.use(validateCookies)

// error handler
app.use((err, req, res, next) => {
  res.status(400).send(err.message)
})

app.listen(3000)
const express = require('express')
const app = express()

const requestTime = function (req, res, next) {
  req.requestTime = Date.now()
  next()
}

app.use(requestTime)

app.get('/', (req, res) => {
  let responseText = 'Hello World!<br>'
  responseText += `<small>Requested at: ${req.requestTime}</small>`
  res.send(responseText)
})

app.listen(3000)

使用中间件

应用程序中间件

app.use('/user/:id', (req, res, next) => {
  console.log('Request URL:', req.originalUrl)
  next()
}, (req, res, next) => {
  console.log('Request Type:', req.method)
  next()
})



app.get('/user/:id', (req, res, next) => {
  console.log('ID:', req.params.id)
  next()
}, (req, res, next) => {
  res.send('User Info')
})

// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', (req, res, next) => {
  res.send(req.params.id)
})

路由级中间件

const express = require('express')
const app = express()
const router = express.Router()

// a middleware function with no mount path. This code is executed for every request to the router
router.use((req, res, next) => {
  console.log('Time:', Date.now())
  next()
})

// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.use('/user/:id', (req, res, next) => {
  console.log('Request URL:', req.originalUrl)
  next()
}, (req, res, next) => {
  console.log('Request Type:', req.method)
  next()
})

// a middleware sub-stack that handles GET requests to the /user/:id path
router.get('/user/:id', (req, res, next) => {
  // if the user ID is 0, skip to the next router
  if (req.params.id === '0') next('route')
  // otherwise pass control to the next middleware function in this stack
  else next()
}, (req, res, next) => {
  // render a regular page
  res.render('regular')
})

// handler for the /user/:id path, which renders a special page
router.get('/user/:id', (req, res, next) => {
  console.log(req.params.id)
  res.render('special')
})

// mount the router on the app
app.use('/', router)

内置中间件

第三方中间件

https://express.js.cn/en/resources/middleware.html

性能优化

https://express.js.cn/en/advanced/best-practice-performance.html

安全优化

https://express.js.cn/en/advanced/best-practice-security.html

TSL/SSL 传输

对于在应用程序中如果会进行敏感数据的处理和传输,此时尽可能的使用传输层的安全协议吧(TLS)来保护连接和数据

这样做的好处是在客户端向服务器发送数据之前对其进行加密,从而防止一些常见的黑客工具吧

尽管 Ajax 和 POST 请求在浏览器中的可能是不明显的,是会被隐藏的,但是在网络环境上容易受到数据包嗅探和中间人工具吧

您可能熟悉安全套接字层 (SSL) 加密。TLS 只是 SSL 的下一个演进。换句话说,如果您以前使用 SSL,请考虑升级到 TLS。通常,我们建议使用 Nginx 来处理 TLS。有关在 Nginx(和其他服务器)上配置 TLS 的良好参考

一个获取免费 TLS 证书的便捷工具是 Let’s Encrypt,这是一个由 互联网安全研究组 (ISRG) 提供的免费、自动化和开放的证书颁发机构 (CA)

减少指纹识别

app.disable('x-powered-by')

它有助于提供额外的安全层,以减少攻击者确定服务器所用软件的能力,这被称为“指纹识别”。虽然指纹识别本身不是一个安全问题,但减少应用程序被指纹识别的能力可以提高其整体安全态势。服务器软件可以通过其对特定请求的响应方式(例如 HTTP 响应头)中的怪癖来被指纹识别。

默认情况下,Express 会发送 X-Powered-By 响应头,您可以使用 app.disable() 方法禁用它

使用 Helmet 中间件

Helmet 可以通过适当设置 HTTP 头部来帮助保护您的应用程序免受一些众所周知的 Web 漏洞攻击。

Helmet 是一个中间件函数,用于设置与安全相关的 HTTP 响应头。Helmet 默认设置以下头部:

  • Content-Security-Policy:一个强大的允许列表,用于指定页面上可以发生什么,从而缓解多种攻击。

  • Cross-Origin-Opener-Policy:有助于页面进程隔离。

  • Cross-Origin-Resource-Policy:阻止他人跨域加载您的资源。

  • Origin-Agent-Cluster:将进程隔离更改为基于来源的。

  • Referrer-Policy:控制 Referer 头部。

  • Strict-Transport-Security:告诉浏览器优先使用 HTTPS。

  • X-Content-Type-Options:避免 MIME 嗅探

  • X-DNS-Prefetch-Control:控制 DNS 预取。

  • X-Download-Options:强制下载保存(仅限 Internet Explorer)。

  • X-Frame-Options:遗留头部,用于缓解 点击劫持 攻击。

  • X-Permitted-Cross-Domain-Policies:控制 Adobe 产品(如 Acrobat)的跨域行为。

  • X-Powered-By:关于 Web 服务器的信息。已移除,因为它可能用于简单的攻击。

  • X-XSS-Protection:遗留头部,试图缓解 XSS 攻击,但反而会使情况更糟,因此 Helmet 禁用了它。

  • secure - 确保浏览器仅通过 HTTPS 发送 Cookie。

  • httpOnly - 确保 Cookie 仅通过 HTTP(S) 发送,而非客户端 JavaScript,有助于防范跨站脚本攻击。

  • domain - 指示 Cookie 的域;用于与请求 URL 的服务器域进行比较。如果匹配,则检查 path 属性。

  • path - 指示 Cookie 的路径;用于与请求路径进行比较。如果此项和域都匹配,则在请求中发送 Cookie。

  • expires - 用于设置持久化 Cookie 的过期日期