编写中间件

概述

中间件函数是在应用程序的请求-响应周期中可以访问 请求对象 (req)、响应对象 (res) 和 next 函数的函数。next 函数是 Express 路由中的一个函数,当被调用时,它会在当前中间件之后执行中间件。

中间件函数可以执行以下任务:

  • 执行任何代码。
  • 更改请求和响应对象。
  • 结束请求-响应周期。
  • 调用堆栈中的下一个中间件。

如果当前中间件函数没有结束请求-响应循环,它必须调用 next() 将控制权传递给下一个中间件函数。否则,请求将被挂起。

下图显示了中间件函数调用的元素:

KMYZYe3RTP8cgSDi/IgPSI2kk8F0k7DUYWC1iOZ2hBGTwNSDHmzZD3Q9z4AaRS49

KMYZYe3RTP8cgSDi/IgPSEoZc5q7jYLoX6vakn5F21EUgyVRJE0zRw7WfvENxYSZ

LQugNMZCgfUZC8IRqGNioz41kb9soYGoHQSiRBZs6Rs=

XsBkmeYryJyL/Z0PhhrWxVx8lEJ6RtEjRHRq3CN8KseTODGwx0cr82z7+10whnpw3ESKEBtQ10+Qx61HsdHD6w==

XsBkmeYryJyL/Z0PhhrWxS/NdeZ/wsMLDiMX6nPuROHJIBwN4XduuLuc5E6Xhtkq/P+36UfRKg2znZ9nrvwSMphMngv9gSWS4nN2WMrnP6A4yxBYeRuKm/z116FNGBjjzAVBqnRbMJvIbBSGe83dwvJFisxlTK6q6Lxc4cz3fq4=

XsBkmeYryJyL/Z0PhhrWxS/NdeZ/wsMLDiMX6nPuROHESvuhvc5c5Verb5nvwhh1X0R1dhuDbfAuGRasLp8DyYskAoQVOm6gFwUM65b7RzeBFzCYebjnHrMu6HBamJKt4k7kWHfMhkFqaobkOF1WiKVtt0J+2OJOVMk3fKOUqMg=

RlQfigRxWJDdnwpccGF1k7iAjxyoC9+F3MD7BK7VUbnPuu5xjYBRWobeZxGfD012VXC4tERQPDC5a7U186Jrg2nkEY60oxiUlTRFfSpp0/KfA7SuZYl94EnOcCPeOGNMfB9wShZ3+1iurghykxhUX8PcY3UQUvDxfwGcFJ5U04pHMibvyOfyMgULYKcTzKPHrqTXh0vBP8C1C1eD15diW0eEiW8nqxzMcO9SbgX/VociJwdS59myAV8ytxOgNyeGJ5WhyLWtt7CkB/uyz9bOsA==

示例

qhTM2xb905p/+xQ90sqrrM7Ar0WDlFDl2hLh6Yq9K1XwweK019BuJFXVdRzLeZQADUdOBM68E59QZ0wx2d+0+PbOq9d0mZP10ghOiDXdK7La7FMM91XzfbnnpWH7hJOSiEKPA67UwpNg8DFy3nLRtVCUdLqOnVYFq+ONMFC0GpSzY3Yzw0Y2Tj6LcOXI2Gm++s/R7pipJhYhf/s1hk/eXAk4PTdJtvXh2aQbT1REcUf1qA634uLtB1nfWUqLQGYTsOZtjnDn9Twf6MoN37A3lfhz9yIL4X2ZFeQpEkwQ65fFTHlGy3If8g2ZEhB2Pmt0Zbn8gFE9iNcnopWToj2wYjEDhwn+ipqX6Lwxk9z3uusaAkW4y76UHQqsip/GmTkePTLZq3kG9WSqkz05oxsogDCImEvDEP10GzrlvvDLjmju4XDV1B6pChJKxzcvMSo13DXnwJsmceAFxRgmjwdzPg==

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

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

app.listen(3000)

中间件函数 myLogger

NqonzPC9LHGG1lODHYTTL1iH3McVht4nBYK9wiKNMOEPVb4Wgv12+UDF8+kmqScA+GEKAT9jcqrqiYUBjcvs0ciyyiFaJPVEYMld84hcqY5YRwpCuOzkn7Suk7O+b9dyfJS2kMZAQOc+PwwIZGFxGWrK+kUYry8fZpOTrqxUC7XPKkfMWPCUr8z70YLli00v5J1DUE02i3kMBP8dzs85+an3aK2aE6G7FL+hY9Oc/wM49WQWrh8QtitXlplTLhTRDajBdnPN86QEVuFlaMN7nXPNQjoOqeXAgG4O+NH0NEY=

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

MB0H/H69Hs8GLwd46ApUeuDpa+CzaKFjMBq6fMne3azR25g8tWuEuqz5hOMMPL1YFsd3jWhb9EjjbXorjH98Fybn8w8Riy/TRq96lSdHmN45LlGMvP/l+5IFQ9Wl1U6k78Wf+IC+3Eyllr0pjQXXMj0BoUaMkVPE6KKwg+fIq5LbtsX/FqDObQ9AafW2dj6YN5nQT3KU/Z2q8LYjTvWimv7LnL4xkVQYiYt6tx2nxYKgbSNzIyLa2+JXgMXXg/fktKTNoLKz1HymPgnGRR6NVY98CnczPntTIYYJXd7DaGK2TAoaGSBuLcmx7isptpX3sFJAavLlE1eQyRh7B8rsr5gEjTo5iL4++KdxmHG6rH9U0PRAeMKL4FxXaBUU/RYEZFzx8z993/js564XZT7lTdWDksM8g63y+0ORX85CEX3IrXLT7NDpVehn4REenxqVIBEpUYgFHyDEMMRvRNe1XnmEWa5gUWs9hzirrRbQRaH09Draxyj44FBk5RqR/eaDpr+wmtOnrTxXnj6baXueGQ==

/9SSttUWkH0sbKJZ+Vl22NhWViRr88CkjrKPollExWOSXAbN9ye34KbKUg1zMV9Abkvh3/R66/Y/Zj7hVQ0aRvJq+Y/7DdZVRCpUnGnh+vcNf5vcrRD+6mt8vOwXnEN8tSXMCWA16Bp0D7RIsQyNnYz6oOfQJo3jXe+uhEvDrmFKDaqbTLqx7CC1+F3+xnYIAC8t3KSoPeX40bU2W55zYYSE+91mkd5R13MAqojPLMwmtAYxrfyGQXgUs3+7HePS

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)

5XTOVRrZYaB0E0e3heT26zaSn8pbDsod09qOr4J3AyD7A7+cnRWKQNJcaXt+wvHFSGVJ8CQ2FOUJ9UNz4EFWB+Lo8UF4GZBhHn2apFcx6g4=

S7A+JzShVR9fJnNS+t3cTIemmayDFrjje76XHcpECyhXXHjz3VjbvFskMVcRUbWm1cXX7xAs9q5GklMQEy86c/AmvsjGkPgQRw86047HSLhFGgaX94t9HNAyF6+Gv+bB

+4H4y7Wxyucsp/dEHEedf7k2WbFfnwhmPRNMI98wkU2fZsTI3/+GktHGUuB0vCCI+ZTkvQwvRlAmyL811qgy/J3WfNgUa4fcVCHG/cjJKkZjx/JfXAcpV4VGTqi4Pc8BesSrWn3nWBPufXAiI12BZRN9eTmyiVizi+tRlt5LVYSae3cRJefmQIvNFkxBgWQDugYsAWLupD1SJTHzFXByp+YRdZw3UjxsQ9JbnbdMshvK6vyn20SUnqY2Er4mNIuWijZQ3dIkZCrNM25B1yyS7w==

4AqL0qZ5x5uHJGzQt1Ea0/gATcIuSHw91cdmjCXnlONJw6mCE4qxSxDGyq7GgXu61CbuX23Mdydian6qv/T7ed+IfDiqAGJebOvZ+UT8dOMhgnVPdRHWXRAoGMx3gPSKezzsdnHQ+O+uD1J13uEN/IRoQTDbvvNc3n9pJ0TYtDI1Etxou1g6tPChD1Ah4P+e5aYXyhVEvC0oiCEXWHPygpGC7mJoSsXlP/OkAdaG7sc=

中间件函数 requestTime

keLXouY8UFH07rB8UfIbMHJn9ca6xfGJ+usfvKNakYi0GTVMIkfgWv0jxMWYLFzAPpxMIlgU7l5L15hBP0EUkN+hQnk5BrxCFSc8A6KHa9AMPelkRFVVzQbDT3/QJ/JXFjKraEXU22TjtPyeA0eSIVqghht1W2mmS2dZWdR323vkrBtFhzKeArX6BE72Ks9MD9rWHP/J6FSvnU1K/xG7lg==

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

pF/SWUNIF1PYiZYQWBD33V8kgb7UA6W7SyzwXiMI1WUQLYiMD2+vbeg+1AC9mZ6dxlCRSMrzfju66cPAayG8vzJYVlfaKPM8KCUJLU3Lxe0u6ojeU1iUnQ7LMNJoZzc7Ullv6bXVZzg4dlz0W4RqsiZEzpcIn1JQmRQOZ9p1Bgo8vkX2U9BWO9/wL0JS4/S0cyyXfexbhhB0cN1Zj+g9I6uStTu2y+1IM2kgmfJTNwfvQ8lXanZgXjQCXNRa102e

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)

t3MSvZWXeb1hAQ1mrOuld3j1/XZkmiTPrVl0b75QIlnSdRqApZ8rRzkR0GpiZIYdyAZGSVUqL0oxOM/lRD1Zxzf9ItDAVWnJPxLGjcnszxEGQ86PqsGY5BHmTvMCjRRTg3Y+2asIaMuSHkGjdL+iq/eKqJdxiZCzpAYWqzuP0+4=

中间件函数 validateCookies

Ztuu+/u9hOOWcvVCvMJWDaRIckoi8mxK4SYsXV1Dct6Dkdwnitc4f1Nbfv0PtyOHV6MFYXsOZSeyo3iuJI0NB08yuLIVnOlfsalmkgW7lyPU6B50Ee2clIaWm6PbVKLDcJR0vETI6yE/Fv1l0IUXp+q03Ztf9sBotE5wtCig17E=

tyk/m+ZEWQV+koveGMgLSxPKmRF4EPKycbQiFsvWSw19bUSoSOAVDITeNBkYUqaJhpebsYl6vxUoZe2699YMlirBwaHulL1VtbC55k9RGyI=

async function cookieValidator (cookies) {
  try {
    await externallyValidateCookie(cookies.testCookie)
  } catch {
    throw new Error('Invalid cookies')
  }
}

bdojGM5iw5xFUHCvg2JBltFDuly+7GATDEkmFO9SMnHaVTvCsQAPIzVa9IUkCI56JndwlZAnyHiaVgeVHxGvC6vGEl3vwNudlHEuTQZL9V0NkgbQ3YdIUVYM/CKwBtpM7O5Q4CmTLQmuhxs/UfSejF0kOSkAIx2ThExh5cwa5yopG6KHlEKs1UTHEzfVnYYw1OOrfignQf1QQzdrJfZSgbQl27C1mO1nChVJor8H4VRz6Bpk/wQ8tuaY3h58EjBnwkSGxk5h3nhTI2qYvJQc/57+NhpS+MLBBKjbL0Xr8SjzkSU6IIjqW1IRFQOrX7KWFaVoSGMNtwea1qZAS2NlS8bUWGMBqZGXL1mZROpfiBLhNk5rKNdhD6cNTNSG9Vc11iaepQQK4ur7LM0lA5DZc0Wjq1Hf33Y/3qbfthh0MsnpjZv5nTniS8X7w/YAqYHInH1Zljrl4lEgDX7ywEjafQ==

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)

IuQaKNpLpLTsEVxqptbKXBsnaggTwmAEFyjagKxA+z6QEq9+R3REGfH0A5M9lOfPh1Ojvs61WQqag1fgf3aB6scXYFUbU6kBpFNqEx8NtwI/PbgetLnXWROs9GZLdBIZ/zj4HkZh/TLQ4AfNGrrN2ufr6ghvlQT42Ar7s1yiXWDWDhiWEsRFJsIPfKaqH41tU3sQOFLQuL3XgUVNFqwwJDjxxURZsgDRcGWU18Qk9qsjh4NwHcFoaBaH0RZ2Ld10Zt4T4ZsAHmSTdFm71VoyR5N/z5H8MCvhEZlwL/hqPh7QwbZugzMgOHF0w2nXOviJwEv32ZJ9tNwxfaUSdrE1ZSjw6lYvfByPx30T1Az5IA5TbbKX8nfAEElksFVSv7lB3HhqDgs0OhDTaTyRBNeyUVXkY2yEbYsSk+bp78gW09N9gm+fV8wO/qc+TBZaZIo9G7ltF6Jpgavlm/4nrbgEVOTOPNLEupNoMs2GZw+54oDORxVFeftv7YPQmQQm8oAVgSCZhnggqG7TizJu4kIYTnf1C+HHaVzkFZ6lFvcYO4W3vDmFbh0rDxXHfFkgHwLNnmiIgp/8ZrbRiLH3AYPoqw==

kwUjnFmz567wswx0aFVzmRCGE5Ze31BMxJ9hkFLzUfyXXn409odMvCHwnwSoyXoEeNkLq98/MLVd0ohEj7qlTGHA7s8dNiHyD+FtlT7jO1H+ZZRaGPQIZ3QU9GS2RYTlsYaxE0hMHutfslH5PW/DT69ObL+xzUbK85xMIWzz7+JEbMCYigQpdVIfGZEf0zaTuwLj++TafwERiVPaX+c+Hc1xKmrwOMC+mnV6UNb1scs=

JYKAV0S9ykjksWw6bboXkTYg1YP1AkkXh5AP+hzRO8DejOXk6rLPrOT1j+4ds0DViycQ5QcHPDVI6qshQrcRpHDBqD+xrM65SwE7mhNz6wCClboEsNg4h8LHGmVmnF4YZO09qSNwy2mNLKnIcGVpXwdD+e1H5UB8R/P9w2C/W3rN07DR8L58xuK/uraSds1F

可配置的中间件

zAoTqD3NFWS9Ev8bwS88HtBTHKaIffTDFS9KB+UHLZu3I9kCIJpu72g/M/l06B3wS/afu2gCVIRYWdBuIDptxs7gtjaxOcji32tlRmV1CnTCZVAV39xRp6+QeL+6iEotX9JkMSvNC6LCxyufa/nVcxxatDOSby6xYvp6Urn5POtBWNllAqiaHxhVeNgY5aZUfQifzUyAF2EY/nhSSRSsXQ==

wlDosAPtngRvlYJOKObFr4InKPIAlbTllWZVOoAUsIIO+q0Mx2XeFq2AEk56MGwT

module.exports = function (options) {
  return function (req, res, next) {
    // Implement the middleware function based on the options object
    next()
  }
}

/y+fnZ2gfs3kgvIw6xCQWdWViT3PvUUvZnc8MOoiHS8uKY7es+UC2Cs6llYHgOSL

const mw = require('./my-middleware.js')

app.use(mw({ option1: '1', option2: '2' }))

4tfMM0wfd/xbxdLOIEBE4lIzTLFnf/XtU60/h2KeW7k12O9HexEeB/uWuAkukzsV/op6yb8bm0mtapnG+e2KSVQgi6NK0zZhxhme79tHUuZdU1QjB4TaYHjdpEXdauxLJfKbYfNQhss+UIHcJ+28CDKcFHOseg66VmV87NHXWvpmtHKVq1Kah0Gt5jOGeGpk50SlpfUF4G+G+TBC6xKA2KNRISB/Gl4Zo7Azhm/EQpa1xrEVCGbieE9gWeL0HrWn