express常用方法

92 阅读15分钟

你好世界示例

下面嵌入的基本上是您可以创建的最简单的 Express 应用程序。它是一个单一的文件应用程序 - 不是你使用Express生成器时得到的,它为一个完整的应用程序创建脚手架,其中包含大量JavaScript文件,Jade模板和用于各种目的的子目录。

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


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




app.listen(port, () => {
console.log(Example app listening on port ${port})
})

app.listen(port, () => { console.log(Example app listening on port ${port}) })

此应用启动服务器并在端口 3000 上侦听连接。该应用程序响应“Hello World! 到根 URL () 或路由。对于其他所有路径,它将响应 404 未找到/

上面的例子实际上是一个工作服务器:继续并单击显示的URL。您将收到回复,页面上有实时日志,您所做的任何更改都将实时反映。这是由RunKit提供支持的,它提供了一个交互式JavaScript游乐场,连接到在Web浏览器中运行的完整Node环境。 以下是在本地计算机上运行同一应用的说明。

RunKit 是与 Express 项目无关的第三方服务。

本地运行

首先创建一个名为 的目录,切换到它并运行 。然后按照安装指南作为依赖项进行安装myappnpm initexpress

在目录中,创建一个名为并复制上述示例中的代码的文件。myappapp.js

(请求)和(响应)是 Node 提供的完全相同的对象,因此您可以调用 、 以及您在不涉及 Express 的情况下执行的任何其他操作。reqresreq.pipe()req.on('data', callback)

使用以下命令运行应用:

$ node app.js

然后,在浏览器中加载以查看输出。http://localhost:3000/

Express 应用程序生成器

通过应用生成器工具 express-generator 可以快速创建一个应用的骨架。

你可以通过 npx (包含在 Node.js 8.2.0 及更高版本中)命令来运行 Express 应用程序生成器。

$ npx express-generator

对于较老的 Node 版本,请通过 npm 将 Express 应用程序生成器安装到全局环境中并使用:

$ npm install -g express-generator
$ express

-h 参数可以列出所有可用的命令行参数:

$ express -h


Usage: express [options] [dir]




Options:



-h, --help          输出使用方法
    --version       输出版本号
-e, --ejs           添加对 ejs 模板引擎的支持
    --hbs           添加对 handlebars 模板引擎的支持
    --pug           添加对 pug 模板引擎的支持
-H, --hogan         添加对 hogan.js 模板引擎的支持
    --no-view       创建不带视图引擎的项目
-v, --view <engine> 添加对视图引擎(view) <engine> 的支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认是 jade 模板引擎)
-c, --css <engine>  添加样式表引擎 <engine> 的支持 (less|stylus|compass|sass) (默认是普通的 css 文件)
    --git           添加 .gitignore
-f, --force         强制在非空目录下创建</code></pre>




例如,如下命令创建了一个名称为 myapp 的 Express 应用。此应用将在当前目录下的 myapp 目录中创建,并且设置为使用 Pug 模板引擎(view engine):



$ express --view=pug myapp


create : myapp
create : myapp/package.json
create : myapp/app.js
create : myapp/public
create : myapp/public/javascripts
create : myapp/public/images
create : myapp/routes
create : myapp/routes/index.js
create : myapp/routes/users.js
create : myapp/public/stylesheets
create : myapp/public/stylesheets/style.css
create : myapp/views
create : myapp/views/index.pug
create : myapp/views/layout.pug
create : myapp/views/error.pug
create : myapp/bin
create : myapp/bin/www




然后安装所有依赖包:



$ cd myapp
$ npm install



在 MacOSLinux 中,通过如下命令启动此应用:



$ DEBUG=myapp:* npm start



在 Windows 命令行中,使用如下命令:



> set DEBUG=myapp:* & npm start



在 WindowsPowerShell 中,使用如下命令:



PS> $env:DEBUG='myapp:*'; npm start



然后在浏览器中打开 http://localhost:3000/ 网址就可以看到这个应用了。




通过生成器创建的应用一般都有如下目录结构:



.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.pug
    ├── index.pug
    └── layout.pug


7 directories, 9 files






通过 Express 应用生成器创建应用只是众多方法中的一种。你可以不使用它,也可以修改它让它符合你的需求。





基本路由



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




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




路由定义采用以下结构:



app.METHOD(PATH, HANDLER)



哪里:




app是 的实例。express
METHOD是一个小写的 HTTP 请求方法。
PATH是服务器上的路径。
HANDLER是路由匹配时执行的函数。






本教程假定已创建 named 的实例并且服务器正在运行。如果不熟悉如何创建应用并启动应用,请参阅 Hello world 示例。expressapp






以下示例说明了如何定义简单路由。




在主页上回复:Hello World!



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



响应应用程序主页根路由 () 上的 POST 请求:/



app.post('/', function (req, res) {
  res.send('Got a POST request')
})



响应对路由的 PUT 请求:/user



app.put('/user', function (req, res) {
  res.send('Got a PUT request at /user')
})



响应对路由的 DELETE 请求:/user



app.delete('/user', function (req, res) {
  res.send('Got a DELETE request at /user')
})



有关路由的更多详细信息,请参阅路由指南。



利用 Express 托管静态文件



为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static 内置中间件函数。




此函数特征如下:



express.static(root, [options])



The root argument specifies the root directory from which to serve static assets. For more information on the options argument, see express.static.




例如,通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:



app.use(express.static('public'))



现在,你就可以访问 public 目录中的所有文件了:



http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html


Express 在静态目录查找文件,因此,存放静态文件的目录名不会出现在 URL 中。



如果要使用多个静态资源目录,请多次调用 express.static 中间件函数:



app.use(express.static('public'))
app.use(express.static('files'))



访问静态资源文件时,express.static 中间件函数会根据目录的添加顺序查找所需的文件。






注意:For best results, use a reverse proxy cache to improve performance of serving static assets.






To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the express.static function, specify a mount path for the static directory, as shown below:



app.use('/static', express.static('public'))



现在,你就可以通过带有 /static 前缀地址来访问 public 目录中的文件了。



http://localhost:3000/static/images/kitten.jpg
http://localhost:3000/static/css/style.css
http://localhost:3000/static/js/app.js
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/hello.html



然而,the path that you provide to the express.static function is relative to the directory from where you launch your node process. If you run the express app from another directory, it’s safer to use the absolute path of the directory that you want to serve:



const path = require('path')
app.use('/static', express.static(path.join(__dirname, 'public')))



欲了解更多关于 serve-static 函数及其参数的知识,请参考 serve-static。



路由



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




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




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




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




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



var express = require('express')
var app = express()


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



路由方法



路由方法派生自其中一个 HTTP 方法,并附加到类的实例。express




以下代码是为 GETPOST 方法定义的到应用根目录的路由示例。



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


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




Express 支持对应于所有 HTTP 请求方法的方法:、 等。 有关完整列表,请参阅应用程序。方法。getpost




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



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


路由路径



路由路径与请求方法相结合,定义可以发出请求的终结点。路由路径可以是字符串、字符串模式或正则表达式。




字符 、 、 和 是其正则表达式对应项的子集。连字符 () 和点 () 由基于字符串的路径逐字解释。?+*()-.




如果需要在路径字符串中使用美元字符 (),请将其转义括在 和 中。例如,“” 处请求的路径字符串将为 “”。$([])/data/$book/data/([\$])book






Express 使用路径到正则表达式来匹配路由路径;请参阅正则表达式路径文档,了解定义路由路径的所有可能性。快速路线测试器是用于测试基本快速路线的便捷工具,尽管它不支持模式匹配。








查询字符串不是路由路径的一部分。






下面是一些基于字符串的路由路径示例。




此路由路径会将请求与根路由 ./



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



此路由路径会将请求与 匹配。/about



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



此路由路径会将请求与 匹配。/random.text



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



下面是基于字符串模式的路由路径的一些示例。




此路由路径将匹配 和 。acdabcd



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



此路由路径将匹配 、、 等。abcdabbcdabbbcd



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



此路由路径将匹配 、、 等。abcdabxcdabRANDOMcdab123cd



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



此路由路径将匹配 和 。/abe/abcde



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



基于正则表达式的路由路径示例:




此路由路径将匹配任何带有“a”的内容。



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



此路由路径将匹配 和 ,但不匹配 、 等。butterflydragonflybutterflymandragonflyman



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


路由参数



路由参数是命名的 URL 段,用于捕获在 URL 中的位置指定的值。捕获的值填充在对象中,路径中指定的 route 参数的名称作为其各自的键。req.params



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



要使用路由参数定义路由,只需在路由路径中指定路由参数,如下所示。



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





路由参数的名称必须由“字字符”([A-Za-z0-9_])组成。






由于连字符 () 和点 () 是按字面解释的,因此它们可以与路由参数一起使用以用于有用的目的。-.



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" }



要更好地控制可由路由参数匹配的确切字符串,可以在括号 () 中附加正则表达式:()



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





由于正则表达式通常是文本字符串的一部分,因此请确保使用额外的反斜杠转义任何字符,例如 。\\\d+








在 Express 4.x 中,正则表达式中的 * 字符不会以通常的方式解释。解决方法是使用 代替 。这可能会在Express 5中修复。{0,}*





路由处理程序



您可以提供多个行为类似于中间件的回调函数来处理请求。唯一的例外是这些回调可能会调用以绕过其余的路由回调。您可以使用此机制对路由施加前提条件,如果没有理由继续使用当前路由,则将控制权传递给后续路由。next('route')




路由处理程序可以是函数、函数数组或两者的组合,如以下示例所示。




单个回调函数可以处理路由。例如:



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



多个回调函数可以处理一个路由(确保指定对象)。例如:next



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



回调函数数组可以处理路由。例如:



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


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




var cb2 = function (req, res) {
res.send('Hello from C!')
}




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




独立函数和函数数组的组合可以处理路由。例如:



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


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




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



响应方法



下表中响应对象 () 上的方法可以向客户端发送响应,并终止请求-响应周期。如果未从路由处理程序调用这些方法,则客户端请求将保持挂起状态。res





方法	
描述




res.download()	
提示下载文件。



res.end()	
结束响应过程。



res.json()	
发送 JSON 响应。



res.jsonp()	
发送支持 JSONP 的 JSON 响应。



res.redirect()	
重定向请求。



res.render()	
呈现视图样板。



res.send()	
发送各种类型的响应。



res.sendFile()	
将文件作为八位字节流发送。



res.sendStatus()	
设置响应状态代码并将其字符串表示形式作为响应正文发送。




app.route()



可以使用 为路由路径创建可链接的路由处理程序。 由于路径是在单个位置指定的,因此创建模块化路由很有帮助,减少冗余和拼写错误也很有帮助。有关路由的更多信息,请参阅:路由器() 文档。app.route()




下面是使用 定义的链式路由处理程序的示例。app.route()



app.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.RouterRouter




以下示例将路由器创建为模块,在其中加载中间件函数,定义一些路由,并将路由器模块挂载到主应用程序中的路径上。




创建应用目录中命名的路由器文件,内容如下:birds.js



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


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




module.exports = router




然后,在应用程序中加载路由器模块:



var birds = require('./birds')


// ...




app.use('/birds', birds)




应用现在将能够处理对 和 的请求,以及调用特定于路由的中间件函数。/birds/birds/abouttimeLog



使用中间件



Express 是一个路由和中间件 Web 框架,它自己的功能很少:Express 应用程序本质上是一系列中间件函数调用。




中间件函数是有权访问请求对象 ()、响应对象 () 和应用程序请求-响应周期中的下一个中间件函数的函数。下一个中间件函数通常由名为 的变量表示。reqresnext




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




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




如果当前中间件函数没有结束请求-响应周期,则必须调用以将控制权传递给下一个中间件函数。否则,请求将保持挂起状态。next()




快速应用程序可以使用以下类型的中间件:




应用级中间件
路由器级中间件
错误处理中间件
内置中间件
第三方中间件




您可以使用可选的挂载路径加载应用程序级和路由器级中间件。 您还可以一起加载一系列中间件函数,从而在挂载点创建中间件系统的子堆栈。



应用级中间件



使用 and 函数将应用程序级中间件绑定到应用程序对象的实例,其中中间件函数以小写形式处理的请求(例如 GETPUTPOST)的 HTTP 方法。app.use()app.METHOD()METHOD




此示例显示了一个没有挂载路径的中间件函数。每次应用收到请求时都会执行该函数。



var express = require('express')
var app = express()


app.use(function (req, res, next) {
console.log('Time:', Date.now())
next()
})




此示例显示了挂载在路径上的中间件函数。该函数适用于任何类型的 路径上的 HTTP 请求。/user/:id/user/:id



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



此示例显示路由及其处理程序函数(中间件系统)。该函数处理对路径的 GET 请求。/user/:id



app.get('/user/:id', function (req, res, next) {
  res.send('USER')
})



下面是使用挂载路径在挂载点加载一系列中间件函数的示例。 它演示了一个中间件子堆栈,该子堆栈将任何类型的 HTTP 请求的请求信息打印到路径。/user/:id



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



路由处理程序使您能够为路径定义多个路由。下面的示例为 GET 请求定义了两个路由到路径。第二个路由不会导致任何问题,但永远不会被调用,因为第一个路由结束了请求-响应周期。/user/:id




此示例显示了一个中间件子堆栈,用于处理对路径的 GET 请求。/user/:id



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


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




要跳过路由器中间件堆栈中的其余中间件功能,请调用以将控制权传递给下一个路由。注意:仅适用于使用 or 函数加载的中间件函数。next('route')next('route')app.METHOD()router.METHOD()




此示例显示了一个中间件子堆栈,用于处理对路径的 GET 请求。/user/:id



app.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next route
  if (req.params.id === '0') next('route')
  // otherwise pass the control to the next middleware function in this stack
  else next()
}, function (req, res, next) {
  // send a regular response
  res.send('regular')
})


// handler for the /user/:id path, which sends a special response
app.get('/user/:id', function (req, res, next) {
res.send('special')
})




中间件也可以在数组中声明以实现可重用性。




此示例显示了一个具有中间件子堆栈的数组,该子堆栈处理对路径的 GET 请求/user/:id



function logOriginalUrl (req, res, next) {
  console.log('Request URL:', req.originalUrl)
  next()
}


function logMethod (req, res, next) {
console.log('Request Type:', req.method)
next()
}




var logStuff = [logOriginalUrl, logMethod]
app.get('/user/:id', logStuff, function (req, res, next) {
res.send('User Info')
})



路由器级中间件



路由器级中间件的工作方式与应用程序级中间件相同,只是它绑定到 的实例。express.Router()



var router = express.Router()



使用 and 函数加载路由器级中间件。router.use()router.METHOD()




以下示例代码使用路由器级中间件复制上面显示的应用程序级中间件的中间件系统:



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


// a middleware function with no mount path. This code is executed for every request to the router
router.use(function (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', function (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}, function (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', function (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()
}, function (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', function (req, res, next) {
console.log(req.params.id)
res.render('special')
})




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




要跳过路由器的其余中间件功能,请调用以将控制权传回路由器实例。next('router')




此示例显示了一个中间件子堆栈,用于处理对路径的 GET 请求。/user/:id



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


// predicate the router with a check and bail out when needed
router.use(function (req, res, next) {
if (!req.headers['x-auth']) return next('router')
next()
})




router.get('/user/:id', function (req, res) {
res.send('hello, user!')
})




// use the router and 401 anything falling through
app.use('/admin', router, function (req, res) {
res.sendStatus(401)
})



错误处理中间件





错误处理中间件始终采用四个参数。您必须提供四个参数才能将其标识为错误处理中间件函数。即使不需要使用该对象,也必须指定它以维护签名。否则,该对象将被解释为常规中间件,并且无法处理错误。nextnext






定义错误处理中间件函数的方式与其他中间件函数相同,除了使用四个参数而不是三个参数,特别是使用签名):(err, req, res, next)



app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})



有关错误处理中间件的详细信息,请参阅:错误处理。



内置中间件



从版本 4.x 开始,Express 不再依赖于 Connect。中间件 以前包含在 Express 中的功能现在位于单独的模块中;请参阅中间件函数列表。




Express 具有以下内置中间件功能:




express.static 提供静态资产,如 HTML 文件、图像等。
express.json 使用 JSON 有效负载解析传入请求。注意:适用于快速版 4.16.0+
express.urlencoded 使用 URL 编码的有效负载解析传入请求。注意:适用于快速版 4.16.0+



第三方中间件



使用第三方中间件向 Express 应用程序添加功能。




安装 Node.js 模块以实现所需的功能,然后在应用程序级别或路由器级别将其加载到应用中。




以下示例说明了安装和加载 cookie 解析中间件函数。cookie-parser



$ npm install cookie-parser


var express = require('express')
var app = express()
var cookieParser = require('cookie-parser')


// load the cookie-parsing middleware
app.use(cookieParser())




有关通常与 Express 一起使用的第三方中间件函数的部分列表,请参阅:第三方中间件。



在代理背后表达



在反向代理后面运行快速应用时,某些快速 API 可能会返回与预期不同的值。为了对此进行调整,可以使用应用程序设置在 Express API 中公开反向代理提供的信息。最常见的问题是,公开客户端 IP 地址的显式 API 可能会显示反向代理的内部 IP 地址。trust proxy






配置设置时,了解反向代理的确切设置非常重要。由于此设置将信任请求中提供的值,因此 Express 中的设置组合必须与反向代理的操作方式相匹配。trust proxy






应用程序设置可以设置为下表中列出的值之一。trust proxy





类型	
价值




布尔	



如果 ,则客户端的 IP 地址被理解为标头中最左侧的条目。trueX-Forwarded-For




如果 ,则应用被理解为直接面向客户端,并且客户端的 IP 地址派生自 。这是默认设置。falsereq.socket.remoteAddress






设置为 时,请务必确保最后一个受信任的反向代理正在删除/覆盖以下所有 HTTP 标头:、、,否则客户端可能会提供任何值。trueX-Forwarded-ForX-Forwarded-HostX-Forwarded-Proto








IP 地址	



要信任为反向代理的 IP 地址、子网或 IP 地址和子网数组。以下列表显示了预配置的子网名称:




回送-127.0.0.1/8::1/128
链接本地 - ,169.254.0.0/16fe80::/10
唯一本地 - , , ,10.0.0.0/8172.16.0.0/12192.168.0.0/16fc00::/7




您可以通过以下任一方式设置 IP 地址:



app.set('trust proxy', 'loopback') // specify a single subnet
app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array




指定后,将从地址确定过程中排除 IP 地址或子网,并将离应用程序服务器最近的不受信任 IP 地址确定为客户机的 IP 地址。这通过检查是否受信任来工作。如果是这样,则从右到左检查中的每个地址,直到第一个不受信任的地址。req.socket.remoteAddressX-Forwarded-For






数	



使用与 Express 应用程序最多相距跃点数的地址。 是第一个跃点,其余的在标题中从右到左查找。值 of 表示第一个不受信任的地址是 ,即没有反向代理。nreq.socket.remoteAddressX-Forwarded-For0req.socket.remoteAddress






使用此设置时,请务必确保 Express 应用程序没有多个不同长度的路径,以便客户端可以小于配置的跃点数,否则客户端可能会提供任何值。








功能	



自定义信任实现。



app.set('trust proxy', function (ip) {
  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs
  else return false
})







启用将产生以下影响:trust proxy







req.hostname 的值派生自标头中设置的值,该值可由客户端或代理设置。X-Forwarded-Host






X-Forwarded-Proto可以通过反向代理设置,以告诉应用程序它是无效名称还是无效名称。此值由 req.protocol 反映。httpshttp






req.ip 和 req.ips 值根据套接字地址和标头填充,从第一个不受信任的地址开始。X-Forwarded-For







该设置是使用代理地址包实现的。有关详细信息,请参阅其文档。trust proxy