路由

路由是指应用程序的端点 (URI) 如何响应客户端请求。有关路由的介绍,请参见 基本路由

您使用与 HTTP 方法对应的 Express app 对象的方法定义路由;例如,app.get() 处理 GET 请求,app.post 处理 POST 请求。如需完整列表,请参阅 app.METHOD。您还可以使用 app.all() 处理所有 HTTP 方法,使用 app.use() 指定中间件作为回调函数(详见 使用中间件)。

这些路由方法指定了一个回调函数(有时称为 "handler functions"),当应用程序接收到对指定路由(端点)和 HTTP 方法的请求时调用。换句话说,应用程序 "listens" 对于匹配指定路由和方法的请求,当它检测到匹配时,它会调用指定的回调函数。

实际上,路由方法可以有多个回调函数作为参数。对于多个回调函数,重要的是提供 next 作为回调函数的参数,然后在函数体中调用 next() 以将控制权移交给下一个回调。

下面的代码是一个非常基本的路由示例。

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

// respond with "hello world" when a GET request is made to the homepage
app.get('/', (req, res) => {
  res.send('hello world')
})

路由方法

2cFxp//ABFOFX3TgikFP10ZWcGsjE16QSrJLLJQup57UV/hYk9TW7XQew+V+KLMf+BJ7PznF7tUaVirBRO3bzKve3TSrR6JDP3FmXuEPLj2o8m25czqMsxSzNVHGh93n

zGTPA53bKTsWHkpwjz6CSuNZWcRgKvDjK8FqNodgLMnw0EixqpEKncO9SOnSR2tm0lLNefv00T705PCDOXRjqH3rrwyEs/+GmXvGInITBD8yToxitYvyp9UBUFSZGOMO

// GET method route
app.get('/', (req, res) => {
  res.send('GET request to the homepage')
})

// POST method route
app.post('/', (req, res) => {
  res.send('POST request to the homepage')
})

2Xh8+z9Hu6W3l5kuiwndvwQZ/unLcMM6pzveZgz/bL7vXRjUiCA8TRCOGmiDGC7ZtiF/RwbU4RB8Ziw/LCvIhyHdWuP4yuVQnVqQlNbBS7uycXf02Fyj5CWGbnj4+O5odSTYPAbcyOYfhuLmJJhkOV5SBYhbPJcFG+Ud+aROz5CbAAGuJlxubSU1lKhIRt3S56WkjVMY6rMfzqskoBWhYlUd63m5ij9sk4TXhmUci1Wi25NRJruqG/dv9Dw94db9c+/z7VSzqM1qnCnNTpYvzQ==

RfftfEF6n38LWDszRihDKFfehq68U72iwLB53G4VK059GLBNK7CwsJPGu4S0ovcnlYmkW+YYVFY5uXzA4CrGHMxbxlPhZEAcA+WQz39qMtjfGBLJYdg9gQElLsbyQ/rlrxCUJkMQ8eX+W9+PYStVwv+T18VBkHdXHvNvFwHXTW6W8Pud4l7/XpDwbFRQ3mTr0gIBpnT4/PjEbRTKpCFSaEFj8d6nq8nnTQ5kE3TnVOZ62cJ9u8RsrQDQKaZ7O7XPqwyh0YqDAOFX/HvdIPZ27I6owCZ/DSGWds6D0oTEybUgUd359gBxv9cG8oVJ5V9WgESE6kiGZ5MXeBoPE4DxMEkHyhn6HUm+xGsRVLfOOvzOfUXzvFTGalFdTuCqt28o+fePDSMWJ19Sw5yF2iQQvMM5cyuaj2OFfxmvN8zo5N97GlKB4t9XyRFlJU6yzAqoLKPlGPb/T8TRgEeJGp3X0w==

app.all('/secret', (req, res, next) => {
  console.log('Accessing the secret section ...')
  next() // pass control to the next handler
})

路由路径

6YlJ7XK+BP3eAjsZKCx73Jklc/kJO3v8boWhcohmvAFm5aC+oq6b9vEJzHCkdQwE8cG8Imzesu8np5gNFZTC+FT6y1YjRa54Yf/G1ee5NJdSNQCBNuFlj6p3Kt89wjjnntq5m1kd3WrqesZs68vETpydm1pTFcY71uNjYZbHpZWXdRTM/MkbSyJmrNVtKA4Zj5g4c90ogBwRUZcF+O7Lcg==

N8jH4SGrFJsLnvO6sQLd2kJOLflSLvjMe7rqzzQGR2anvXPx3Ed0CedLzM4lheaFO3aVDCugBQjLk2z+ptobPNTqBbItjzefYQPyzk3I7pMKAAC6u2kuizOiAQzmtWY/wVHBh70Or2jJdO2FdIJfbAYJmIdjwxXZg3g2S/0qzlYmq+fSo1zzANorw3PPz53V7hpAkujuboDimGkrqDhlJ2iY+ecW+t4oX5MekNn+gIIGNiqswzH4HwsoDX8jh2TMbubTg0IaogQQPvDmjQctyuS+N8z9hIX56dKa6PcFGHU=

+2ozXFpwTBQgC4PXjkIry+UCS0CQd1+vzc2PyWDyUVyD3p0JC9CMPYfGJOUOHg6DaeDMeepxTQNRXw1SdZkO+4pFKzcqaIx4QD6oec0wbXS90EmMy3lFTb7I95fyCj/foimYL1+fTTZCThzccdQzveCxfnCJE3t41uazFzM84Ytl9cDve9JATj1W74LWnPxXpZYgJIG2/kDoGqxHU0lPI9aXk0/Fw3Wl8s8p68PPr0YcgXgRS/cJsbKIUvGEeYx8mtO2+zONrkmAABmDLAoGL0ObKtSpgFSiozt+K2a1Qi+LojQcpnytb/xg6O56RNbs82KgrHTrFgWKqDKvkmXMTQ==

tkA/62l6oQqPff520Mzi70iKwcemRz23/gtZtK6Um48CXcJhgnhw82YSwlJXNO6E9UhNn7sOMEKsZefipPMlqPywF+V1SP853bjfknZTgpwtes4PWiqmyODZ8MwXkGQ9PshZAPBwMKcDIYJZCbz+gzlD1ZxNE9Bu+hEIdzoO5jyJjtkLZXyNGrvduQmpi6mUEU6GhcFynK4RTZ5a4kMqMhmBjG5RkG0b6Bav2/mEwjXXFXls7scEEcD7pgOpcyaTRyEaivzLRDVXu2YXc/JR0McE9b1mM/yyUscJoHLiv8+NqeLoTsr1ZmbuEuXB2eFbkU43KarAZc2Qg6/BZ8EGyQcX2Bc6y+OKFGFAdUo0OKq83tupDeqoCAUAUBm5yy7LWZEU5bUh8v/T5X1qg3/dknTGyCPxY1cXIM6yGukR0jfC5lwzVEOx61gtdG9Xi3ZG3JGapunKz1l6www1K3uG5w==

CgxMDvvWDOYtX48ZnGN7yR2TR72gWCYXU55IK3OxPn22/iiMiPb7sX0pOEYOFMCAT1VaNW6OLLD1i3gI+XKSVw==

XulqhKFbDw24qvX8CaONyQdwmV4T6I+rUITBoMt5PsFWeuJSJJnnJUBGY0/hnDZurFHAPDOZYT0lhGoofpEkrQ==

0F4DzAZzZ558Fh5QNvgm7GPiSVaJX4zlHhuXcWamp/ME/VvlXOqfja01QWFVgOEtm4eguDSc3zIccl0xDmLcFKa+RdJ0+lwREc0qSaR/XWg=

app.get('/', (req, res) => {
  res.send('root')
})

0F4DzAZzZ558Fh5QNvgm7OfyE8zT1cezi5jzOQ4Mh2Kq3I2QTTnBDWze4yzt4SUEpDPoC5QseDzY7hdlOHVDXg==

app.get('/about', (req, res) => {
  res.send('about')
})

0F4DzAZzZ558Fh5QNvgm7OfyE8zT1cezi5jzOQ4Mh2JikQZvcbGiSIFV4TweDhp8Dflr0DG34J12P5VreX7yWiP3q3WofQpg8PcLCslObTQ=

app.get('/random.text', (req, res) => {
  res.send('random.text')
})

XulqhKFbDw24qvX8CaONyWpP3uG5RH1OcXa1fnJGrPHsqBpGr1HLloytrfIMNxohYitmneWhmDSrZOE/ZdDYqg==

0F4DzAZzZ558Fh5QNvgm7AUMLw0BxRsl+g3Q6tVDUfR9ij0K4tZ5/Cvi84bPFZcGYw5d5LvxhT9pKTmnuS1Ljwkj7vTReuq83hn/S2RLtes=

app.get('/ab?cd', (req, res) => {
  res.send('ab?cd')
})

0F4DzAZzZ558Fh5QNvgm7AUMLw0BxRsl+g3Q6tVDUfSRGaR/DXRe95L721kfzvja54zUjVG8fi/WT9OdB3gE20CELV8Eh6BQg4MLzp4tcLMNTUR5xHgIvQfrZ4MtkG0q

app.get('/ab+cd', (req, res) => {
  res.send('ab+cd')
})

0F4DzAZzZ558Fh5QNvgm7AUMLw0BxRsl+g3Q6tVDUfSRGaR/DXRe95L721kfzvja1INjt4BI8Jo5dSf6RO5sE1YKE23vPMAE354J+7TpVt6T/4mdgimFY9b/GB6jsOgQeyRX9up33FUIgrQKAnFPfZBedcWIQr+ZbSWA3gQlPLQ=

app.get('/ab*cd', (req, res) => {
  res.send('ab*cd')
})

0F4DzAZzZ558Fh5QNvgm7LWEleCl//YDfTg3elFvmaJAsA2tZxSywrNUua5ooNJw9FChsYSXz3w/E6ho8RPZF3aT9IGt5Y8NwVnpdPPXt8k=

app.get('/ab(cd)?e', (req, res) => {
  res.send('ab(cd)?e')
})

L5pEjc1ld4pDDOtDtqNDt5zQstQRkGeD0E3jAnAcBUcLmDT8PEg2yoQt2nGF/O06

0F4DzAZzZ558Fh5QNvgm7EnNHzdkjTUnWRoNFWFSMAm2OrQWsl37vzLEBEjMI+bBCiz9tzAVNid8ToWKxbLTUg==

app.get(/a/, (req, res) => {
  res.send('/a/')
})

0F4DzAZzZ558Fh5QNvgm7BylOB/sQNgED/VuEZPQNemXxjdAte41Cq0HbdbYk9cUADxQ9mHPYsIAVGAB2R3rZ55QIFRFz3sppSMhgrwVvoTIkxjprjjVs3Eps/URCYQ9h1bQ3an8SLAdewoG1y8aCMmhj3a+LFwHr9NQnCfZmw8GKJgViVi6hbyHAgfhVYX4ekvbgsnvXP1noohRfjwS1A==

app.get(/.*fly$/, (req, res) => {
  res.send('/.*fly$/')
})

路由参数

/RxreBmKjVSTmLuZWlmVR8Vrwgsob17qZrG/kdwtzmKbuoNWpwNHQoy/tPkGbrp1if0qI3XhrRJCsJqjfEJM0fHzl4Rx38gTblmZ7MMCdRpKw5QGOf8i+CDX+CQ5uC2iVwQ9Sb3CvoCMyIEDC/LqSWZVC87R+vBN0QaJeGCQsTG8urdu4/aSqFFgOc23DTaI3izQM9ILxBl8MQpz6Y8BNa0RtJmGuBKNWDhkUMzCUn1QyWWqdItw1dakxt/CT1XUHzTAXncyPNnxVoEWUt6b8A==

Route path: /users/:userId/books/:bookId
Request URL: http://localhost:3000/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }

RVaZL/WRxUc5vxDhvOe+X424wKISXKksyhqjoSsUBiewyy/cUyBoMbLAxgnKDlaL87GkOwi7Ke3IDLka0LNDd/FYOY7BnOMVkn0OSERnU4BGVWlF0Le4dSIMWRrdW5qJ7fzjtR1pdWx3n3TssTKh0Q==

app.get('/users/:userId/books/:bookId', (req, res) => {
  res.send(req.params)
})

W1j+go75iRhzDsgiijpg+c8SYILJfBzBNoGhU7+0TXL5oCHPpx+vWU+KfKszBwyhMF7zyOI4wmLf944KP1fkYolp6gf0yd4NVFRv65eCtPk=

PTuoFI/Ptplm+19Jyioy7qnTQlwk45bTsjUrTnadMvpzXToAehXBDvKpttz69Ya4GNtB+Du9zqCNEqCgRv3QMB657bIMFrbGPSn7DFgzRggPEvj9Lt/o7bAco/NChyN0C6K9B8aCZyl8TDXqqPN6f5DDAeAUGhd1KE3dUnPKUYF2+ycyt6ONCfbxegiLBDjzHJiVlewzZVYysYDYLz4dGg==

Route path: /flights/:from-:to
Request URL: http://localhost:3000/flights/LAX-SFO
req.params: { "from": "LAX", "to": "SFO" }
Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }

AFCVBjSNLddituE38O9znwCG9U6xkjMYFj2I9VN8k0kX+9bfVE5yiWCqCaL3oIgikeBl/atDD2hgX31CnZ5OScx53nE2tIwOsxJ2hauIJQiWdwSim2FZvzeTj05DMik3clmp1qhqCJlOnkRhTf/UQfDQL9zpGEEZTTaPO50sWaEMDmu2c9brNelVF+y05sVk

Route path: /user/:userId(\d+)
Request URL: http://localhost:3000/user/42
req.params: {"userId": "42"}

W4MwS827AzQ63ZBUSD1xwq64FQ5wAjDcxCGElDU9ldaykr596O8nMRx+UK0crTyv4OAXMs1tI5EtX+Qt/5I6DFu1MQ6uJlOYiu3OK7BHhGMGHbKztZDczB5r44dDvSUEpTsTJZIrSJikgETppihlB/Nm5t44QtKi3rA5bcpanL7XNy4Lip1bj4GKuJ07ROble+wM83r2j+jezcDQjKqFowOUpBhp/JfGV0OLyHVbfnU=

w4Z+EjHjX0hlsucwIHO8h8j9RIi6DMIRuzQWeoUIEHXTqs7gdnChz4iHzpkFpeDolGQ75exuNVyrCdIEONxyXoDm5fdsU+xnqMuq1WUXY0mJ7vR2leP2afNcyvnCLL9Qycmww0cQFD+89J+1Q/xVHldC93gHpcy0elVQhb0OkL0+4Af/t6Z5xTBCoJ8fldLhm9VYIIxCKNQDM3NXrqL06wgvo9R1djZulpYdUU8oqXfrtrTq7JbXcBGirbtl9SfpOwg62ynW8wL0IxRz5k/UwmXKii6PLOACnCT2LYnMQLKMjROQsZE+WjBpkNLAjRxZSV4j/ghF0CqFnk74ZQHCVTblhKWrZsn7WNIKB33MD4I=

路由处理程序

juSzjlGIrLmsQPOguNJqWAcgyCbpnbNP1owBl9LCnauiGX14r3o3J7t887qJD6NW+bX4ayQhFAlMk6eTJqfwdnSJVSx7W3rClOSDegkKW5w9IgcTaQFfjEbcOVKn77HCLbilHVvlAZckLCGSRyrxxKrsR3+8jOAgFVpbUW42hNTRwFiA9LhTahcvYWTe4OMuOp+5/ZabCb8fzWwSmADy1yLsyR9gE+LQuXHBqyPTQwyRBQLUc7jubkowTMwe6L9zGgh9QO3DGo5Qui88dibWhh2lQ3J/Md/4MgQXhLAEmqveoBDLp+nxIwq4l3gmDE09vys9mw57WzjbemPoSEzznWg4Sq67EhVIV0Vc7we4dZEPcciv8s0pK4RihsKFnxuCZ/Y568M0P5tWITJKr8Oq7dwVGxAExkCMnXHNk25i+hT1ajhmdyvkGj8zF4vErnzOfMv8cdah1CdXGZvQYiQVUSfJdqlcHRgqGnlMHk+r++Lpt8RDTYA9ffK5BvgYInYD

oKJyhN401cmNm+7l2oN8x1iEnv6uqetpyjGeN6IPSIhs9sw6556DF1QXQlOnFSnQLUc60NspXLbsRCrxiZIGZa1R0/gLMS0mTXbsIH9Fiufr0ZAtQPjuKeoXtH09OOW8xUXJ1UW3qpnJug53gbIazA==

mDxc6+O/hZgbXHW4Z5jVr1MnvbgOxbjkV46N9GQloWe2X9PFeNbXPs4ANmfJe4zqwAvw92ZRi9f8Okc83mgCQw==

app.get('/example/a', (req, res) => {
  res.send('Hello from A!')
})

FZoZq3zIqXWV7re9VcvJbnzIoVO5OHXdnDRHzQsAfgYDFBAeb1myltcIHxqr2eiI4kyikzSBQ5iDYwXMf5B2oIFbiTn3TCPmH1vfZvR6WiLgbw4sgCeUKMZ/9IdynVfAbzOkjayUMIm1CgIXnzVd4MpB03++UYOYXuQB+8V3A04=

app.get('/example/b', (req, res, next) => {
  console.log('the response will be sent by the next function ...')
  next()
}, (req, res) => {
  res.send('Hello from B!')
})

uZjOrCH6+NRST1uXKC11AgzWtJbgzjgSqMk924PB7WWmq9FeUolJcpZxP/EdL10AEoE1JFgAHGTZScx8ei3dGw==

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!')
}

app.get('/example/c', [cb0, cb1, cb2])

/rXygrvgJN3NjdXyAdBeUEQX4KvDnLgM99bxtJqEZC/vdofP4N1u+483qenD08fGrp5nmOxzTOPL4qxNzo1veBMlawuyCpXg11dOrzjK8nI=

const cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

const cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

app.get('/example/d', [cb0, cb1], (req, res, next) => {
  console.log('the response will be sent by the next function ...')
  next()
}, (req, res) => {
  res.send('Hello from D!')
})

响应方法

Me99LoDd11d/jMlYcF6Ic4Dth9C+VQBJsKWJSCoGjtVIV8/uEd2mnVaefemiNPG8H7NddII54f/TScT0j899HAQFkJTyjdZVDI98/gKCLraw2wVXtl6NC48iUMrm1lSkkLelImrWdYcrmhi9N1FLv463uu3kOA7XudXcdGu89MprREALz7RIlKXt2Focn6EGOa1vQeisfZlOgeVCBa9Y1QW3uk8Ovdl1WrtFxQcdJmYvhDCe26aW3Q4xoqUWEOA5cdfsMHtOhFr8xMUKQppBzg==

方法描述
res.download()提示要下载的文件。
res.end()结束响应过程。
res.json()发送 JSON 响应。
res.jsonp()发送带有 JSONP 支持的 JSON 响应。
res.redirect()重定向请求。
res.render()渲染视图模板。
res.send()发送各种类型的响应。
res.sendFile()将文件作为八位字节流发送。
res.sendStatus()设置响应状态码并将其字符串表示形式作为响应正文发送。

app.route()

uS+xbX2WSsPay93a8+3vWmvZPaaOfZfStbFibv0y0u59cuV2WPLnIG7w9diAEwC5kRFd6uowKlnnuQ67gsbbMfmmLQn6m1IR7WR5spf/fdOUsU5n/To9BxipCftjbInXJGeNJLSaTLzMum2aQrMzwNvyTIEH5NfyqkO9TgRnUU9pX4XYRufc5Zx6YBjqs8BEcfdSOVFIgwS3Yd5WIiPpad1W+TwQjwGL9LnjsxGbOgxC2mMM5+cPVlz30k4KKFY8buUItQ9RCd/A9AQgaZqI6qsdHVomn0iRoSLqTuHeiWLxKOp6lHx/PRidThzMhwGUjDSJGBts/ew1Do2L9RXa1c1VJWvxlRPcOHbqXspq4qoXyMBQOFVmNCb16PNE8Heagsiij6gErkEbRzzyADWh3frB5JQJWQt/FipDZSM97zBJZ9nYlk8LqGboJFB1VJRWt9AHcgTcXqdgx3BYSDaWcQ==

YLMPi1rAD0+ue1dEIRkcu6HTZkyWsXP5FHw6MrxvhVG2KaG9pjC2SuRvj+JCh2AiNm9VESs/KlpkA8Xn8PgR9WFBvvlYlT6Xf352qSVhaqnMu5v0rpcZslkkYowCLqvP

app.route('/book')
  .get((req, res) => {
    res.send('Get a random book')
  })
  .post((req, res) => {
    res.send('Add a book')
  })
  .put((req, res) => {
    res.send('Update the book')
  })

express.Router

tFk913XYOFc9utWDhdYvbTR/4F6IBTYOsDeeVDxNM9U7n6athtMKiLXCd8yDN2kmwTUgm46wtPVPH1rS3+YlLE9ASb4UW4/pM3kGmw5xkR2eWhHkOYmy0s3vK4Q09HjKl7RJkfjy00RLDHNh8tEppjQUNHt3ixyKfcAju591kAK5BXA2d1Q+KpNwFwyCYOsodTCmxtXqthxYsukadGakIwXib71TnYP6SH1jIqQj+0Fo0+wVb3GIoAJdlvLwWKxHjS2KRMUCSDl2rwKNPRFqhg==

BRx04RJJ7U6qdkoAlLi36suF2dwJp6+BJyznxR3QqWuFE47FKLqKlvpnVgr1RqmRznH65ZSqUato99OwmkTBhQtp96K5PrC47gEOZQEbE2LjnJ9HuRBDl2S/OAS5dHGeCV08AjQj2Sh+7I4XpsoRomVdTQw+WnwxgG461UuftB+KM0rNKySetGURsi7zvGKFSw06GKn82sXbOUWUGu6JuQ==

cAWYT2Hv3ThRBDToOfQ183vGwW0xQzpawnvTeAW+oO4rllMcqYPD+EN+wiWTWqsOvNwWpPCvOeMOMYcjJmtUf0kN0YcHecPEKgQ2EUuKwvrc3lypwBDGnVTE+i+gfjuB

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

// middleware that is specific to this router
router.use((req, res, next) => {
  console.log('Time: ', Date.now())
  next()
})
// define the home page route
router.get('/', (req, res) => {
  res.send('Birds home page')
})
// define the about route
router.get('/about', (req, res) => {
  res.send('About birds')
})

module.exports = router

89CnmvwO/tPN1qfSarvaw0MuUfNZUeAiYETFmeXT1j6LM/sExly2du88WGyeK3c/6d4BhD+Qu2QLy0lOGPzuyw==

const birds = require('./birds')

// ...

app.use('/birds', birds)

yfZPDsmM36LmvXLK4k7NZk64gYpmO5UfgKpeGmseYdLram1zySpAxQOtz06GOMdqdIps+QmMo+6EVoecMMz/tSp7V0VeL0EFlS80ydt5bUmp0nSc/siG3pNu/Pa/AwJMcVXHQ+wJNauITAkZnxMCGqAMb171z/9l6wvWdISl5txJujsU863Cr8AXBSwB/rbbQRm1l2+KH3Oi3yC6LuCz9NW3stQWsvLgq6k6pGXr/Gk=