From a877620a9e030f8d2e1dbc0e39d57b8148db0659 Mon Sep 17 00:00:00 2001 From: fralonra Date: Tue, 2 Oct 2018 13:06:59 +0800 Subject: [PATCH] Update: pr#1101 --- README.md | 3 +- docs/ContentTypeParser.md | 4 +- docs/Logging.md | 2 +- docs/Reply.md | 4 +- docs/Routes.md | 2 +- docs/{Server-Methods.md => Server.md} | 177 +++++++++++++++++++++++++- 6 files changed, 182 insertions(+), 10 deletions(-) rename docs/{Server-Methods.md => Server.md} (50%) diff --git a/README.md b/README.md index e947203..4ecf6d4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ### 文档目录 * [入门](https://github.com/fastify/docs-chinese/blob/master/docs/Getting-Started.md) -* [服务器方法](https://github.com/fastify/docs-chinese/blob/master/docs/Server-Methods.md) +* [服务器方法](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md) * [路由](https://github.com/fastify/docs-chinese/blob/master/docs/Routes.md) * [日志](https://github.com/fastify/docs-chinese/blob/master/docs/Logging.md) * [中间件](https://github.com/fastify/docs-chinese/blob/master/docs/Middlewares.md) @@ -13,7 +13,6 @@ * [回复](https://github.com/fastify/docs-chinese/blob/master/docs/Reply.md) * [请求](https://github.com/fastify/docs-chinese/blob/master/docs/Request.md) * [Content-Type 解析](https://github.com/fastify/docs-chinese/blob/master/docs/ContentTypeParser.md) -* [工厂函数](https://github.com/fastify/docs-chinese/blob/master/docs/Factory.md) * [插件](https://github.com/fastify/docs-chinese/blob/master/docs/Plugins.md) * [测试](https://github.com/fastify/docs-chinese/blob/master/docs/Testing.md) * [基准测试](https://github.com/fastify/docs-chinese/blob/master/docs/Benchmarking.md) diff --git a/docs/ContentTypeParser.md b/docs/ContentTypeParser.md index 03f83a6..9094010 100644 --- a/docs/ContentTypeParser.md +++ b/docs/ContentTypeParser.md @@ -33,7 +33,7 @@ if (!fastify.hasContentTypeParser('application/jsoff')){ #### Body Parser -你可以用两种方式解析消息主体. 第一种方法在上面演示过了: 你可以添加定制的 content type 解析器来处理请求. 第二种方法你可以在 `addContentTypeParser` API 传递 `parseAs` 参数. 它可以是 `'string'` 或者 `'buffer'`. 如果你使用 `parseAs` 选项 Fastify 会处理 stream 并且进行一些检查,比如消息主体的 [最大尺寸](https://github.com/fastify/docs-chinese/blob/master/docs/Factory.md#factory-body-limit) 和消息主体的长度. 如果达到了某些限制,自定义的解析器就不会被调用. +你可以用两种方式解析消息主体. 第一种方法在上面演示过了: 你可以添加定制的 content type 解析器来处理请求. 第二种方法你可以在 `addContentTypeParser` API 传递 `parseAs` 参数. 它可以是 `'string'` 或者 `'buffer'`. 如果你使用 `parseAs` 选项 Fastify 会处理 stream 并且进行一些检查,比如消息主体的 [最大尺寸](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md#factory-body-limit) 和消息主体的长度. 如果达到了某些限制,自定义的解析器就不会被调用. ```js fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) { @@ -52,7 +52,7 @@ fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function ##### 自定义解析器的选项 + `parseAs` (string): `'string'` 或者 `'buffer'` 定义了如何收集进来的数据. 默认是 `'buffer'`. -+ `bodyLimit` (number): 自定义解析器能够接收的最大的数据长度, 比特为单位. 默认是全局的消息主体的长度限制[`Fastify 工厂方法`](https://github.com/fastify/docs-chinese/blob/master/docs/Factory.md#bodylimit). ++ `bodyLimit` (number): 自定义解析器能够接收的最大的数据长度, 比特为单位. 默认是全局的消息主体的长度限制[`Fastify 工厂方法`](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md#bodylimit). #### 捕获所有 有些情况下你需要捕获所有的 content type. 通过 Fastify, 你只需添加`'*'` content type. diff --git a/docs/Logging.md b/docs/Logging.md index 0d2fe7b..90c2812 100644 --- a/docs/Logging.md +++ b/docs/Logging.md @@ -41,7 +41,7 @@ fastify.get('/', options, function (request, reply) { ``` -默认情况下,Fastify 给每个请求分配了一个 id 以便跟踪。如果头部存在 "request-id" 即使用该值,否则会生成一个新的增量 id。你可以通过 Fastify 工厂函数的 [`requestIdHeader`](./Factory.md#factory-request-id-header) 选项来自定义该头部的名称。 +默认情况下,Fastify 给每个请求分配了一个 id 以便跟踪。如果头部存在 "request-id" 即使用该值,否则会生成一个新的增量 id。你可以通过 Fastify 工厂函数的 [`requestIdHeader`](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md#factory-request-id-header) 选项来自定义该头部的名称。 此外,你还可以通过 `genReqId` 选项生成自定义的请求 id。它的参数是来访的请求。 ```js let i = 0 diff --git a/docs/Reply.md b/docs/Reply.md index 77e0f82..b0c872d 100644 --- a/docs/Reply.md +++ b/docs/Reply.md @@ -169,10 +169,10 @@ fastify.get('/', function (request, reply) { }) ``` -如果你想完全自定义错误响应,请看 [`setErrorHandler`](https://github.com/fastify/docs-chinese/blob/master/docs/Server-Methods.md#seterrorhandler) API。 +如果你想完全自定义错误响应,请看 [`setErrorHandler`](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md#seterrorhandler) API。 `status` 或 `statusCode` 属性为 `404` 的错误,会被导引到 not found 的处理函数。 -更多信息,详见 [`server.setNotFoundHandler`](https://github.com/fastify/docs-chinese/blob/master/docs/Server-Methods.md#setnotfoundhandler) +更多信息,详见 [`server.setNotFoundHandler`](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md#setnotfoundhandler) API: ```js diff --git a/docs/Routes.md b/docs/Routes.md index ab440d0..95b716f 100644 --- a/docs/Routes.md +++ b/docs/Routes.md @@ -229,7 +229,7 @@ module.exports = function (fastify, opts, next) { 在 Fastify 中为路由里设置不同的日志级别是十分容易的。
你只需在插件或路由的选项里设置 `logLevel` 为相应的[值](https://github.com/pinojs/pino/blob/master/docs/API.md#discussion-3)即可。 -要注意的是,如果在插件层面上设置了 `logLevel`,那么 [`setNotFoundHandler`](https://github.com/fastify/docs-chinese/blob/master/docs/Server-Methods.md#setnotfoundhandler) 和 [`setErrorHandler`](https://github.com/fastify/docs-chinese/blob/master/docs/Server-Methods.md#seterrorhandler) 也会受到影响。 +要注意的是,如果在插件层面上设置了 `logLevel`,那么 [`setNotFoundHandler`](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md#setnotfoundhandler) 和 [`setErrorHandler`](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md#seterrorhandler) 也会受到影响。 ```js // server.js diff --git a/docs/Server-Methods.md b/docs/Server.md similarity index 50% rename from docs/Server-Methods.md rename to docs/Server.md index 4175f16..185911c 100644 --- a/docs/Server-Methods.md +++ b/docs/Server.md @@ -1,10 +1,183 @@

Fastify

-## 服务器方法 +
+## 工厂函数 + +Fastify 模块导出了一个工厂函数,可以用于创建新的 Fastify server 实例。这个工厂函数的参数是一个配置对象,用于自定义最终生成的实例。本文描述了这一对象中可用的属性。 + + +### `http2` (实验性) + +设置为 `true`,则会使用 Node.js 原生的 [HTTP/2](https://nodejs.org/dist/latest-v8.x/docs/api/http2.html) 模块来绑定 socket。 + ++ 默认值: `false` + + +### `https` + +用于配置服务器的 TLS socket 的对象。其选项与 Node.js 原生的 [`createServer` 方法](https://nodejs.org/dist/latest-v8.x/docs/api/https.html#https_https_createserver_options_requestlistener)一致。 +当值为 `null` 时,socket 连接将不会配置 TLS。 + +当 +http2 + 选项设置时,`https` 选项也会被应用。 + ++ 默认值: `null` + + +### `ignoreTrailingSlash` + +Fastify 使用 [find-my-way](https://github.com/delvedor/find-my-way) 处理路由。该选项为 `true` 时,尾斜杠将被省略。 +这一选项应用于 server 实例上注册的*所有*路由。 + ++ 默认值: `false` + +```js +const fastify = require('fastify')({ + ignoreTrailingSlash: true +}) + +// 同时注册 "/foo" 与 "/foo/" +fastify.get('/foo/', function (req, reply) { + res.send('foo') +}) + +// 同时注册 "/bar" 与 "/bar/" +fastify.get('/bar', function (req, reply) { + res.send('bar') +}) +``` + + +### `maxParamLength` +你可以为通过 `maxParamLength` 选项为带参路由 (无论是标准的、正则匹配的,还是复数的) 设置最大参数长度。选项的默认值为 100 字符。
+当使用正则匹配的路由时,这非常有用,可以帮你抵御 [DoS 攻击](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)。
+*当达到长度限制时,将触发 not found 路由。* + + +### `bodyLimit` + +定义服务器可接受的最大 payload,以字节为单位。 + ++ 默认值: `1048576` (1MiB) + + +### `logger` + +Fastify 依托 [Pino](https://getpino.io/) 内建了一个日志工具。该属性用于配置日志实例。 + +属性可用的值为: + ++ 默认: `false`。禁用日志。所有记录日志的方法将会指向一个空日志工具 [abstract-logging](https://npm.im/abstract-logging) 的实例。 + ++ `pinoInstance`: 一个已被实例化的 Pino 实例。内建的日志工具将指向这个实例。 + ++ `object`: 标准的 Pino [选项对象](https://github.com/pinojs/pino/blob/c77d8ec5ce/docs/API.md#constructor)。 +它会被直接传递进 Pino 的构造函数。如果下列属性未在该对象中定义,它们将被相应地添加: + * `genReqId`: 一个同步函数,用于生成请求的标识符。默认生成按次序排列的标识符。 + * `level`: 最低的日志级别。若未被设置,则默认为 `'info'`。 + * `serializers`: 序列化函数的哈希。默认情况下,序列化函数应用在 `req` (来访的请求对象)、`res` (发送的响应对象) 以及 `err` (标准的 `Error` 对象) 之上。当一个日志方法接收到含有上述任意属性的对象时,对应的序列化器将会作用于该属性。举例如下: + ```js + fastify.get('/foo', function (req, res) { + req.log.info({req}) // 日志输出经过序列化的请求对象 + res.send('foo') + }) + ``` + 用户提供的序列化函数将会覆盖对应属性默认的序列化函数。 + + +### `serverFactory` +通过 `serverFactory` 选项,你可以向 Fastify 传递一个自定义的 http server。
+`serverFactory` 函数的参数为 `handler` 函数及一个选项对象。`handler` 函数的参数为 `request` 和 `response` 对象,选项对象则与你传递给 Fastify 的一致。 + +```js +const serverFactory = (handler, opts) => { + const server = http.createServer((req, res) => { + handler(req, res) + }) + + return server +} + +const fastify = Fastify({ serverFactory }) + +fastify.get('/', (req, reply) => { + reply.send({ hello: 'world' }) +}) + +fastify.listen(3000) +``` +Fastify 内在地使用 Node 原生 http server 的 API。因此,如果你使用一个自定义的 server,你必须保证暴露了相同的 API。不这么做的话,你可以在 `serverFactory` 函数内部 `return` 语句之前,向 server 实例添加新的属性。 + + +### `caseSensitive` + +默认值为 `true`,此时路由对大小写敏感。这就意味着 `/foo` 与 `/Foo` 是两个不同的路由。当该选项为 `false` 时,路由大小写不敏感,`/foo`、`/Foo` 以及 `/FOO` 都是一样的。 + +将 `caseSensitive` 设置为 `false` 也会导致所有路由参数 (包括正则匹配的值) 变为小写。 + +```js +fastify.get('/user/:username', (request, reply) => { + // 原 URL: /user/NodeJS + console.log(request.params.username) // -> 'nodejs' +}) +``` + +要注意的是,将该选项设为 `false` 与 [RFC3986](https://tools.ietf.org/html/rfc3986#section-6.2.2.1) 相悖。 + + +### `requestIdHeader` + +用来获知请求 id 的 header 名。请看[请求 id](https://github.com/fastify/docs-chinese/blob/master/docs/Logging.md#logging-request-id) 一节。 + ++ 默认值: `'request-id'` + + +### `trustProxy` + +通过开启 `trustProxy` 选项,Fastify 会认为使用了代理服务,且 `X-Forwarded-*` header 是可信的,否则该值被认为是极具欺骗性的。 + +```js +const fastify = Fastify({ trustProxy: true }) +``` + ++ 默认值: `false` ++ `true/false`: 信任所有代理 (`true`) 或不信任任意的代理 (`false`)。 ++ `string`: 只信任给定的 IP/CIDR (例如 `'127.0.0.1'`)。可以是一组用英文逗号分隔的地址 (例如 `'127.0.0.1,192.168.1.1/24'`)。 ++ `Array`: 只信任给定的 IP/CIDR 列表 (例如 `['127.0.0.1']`)。 ++ `number`: 信任来自前置代理服务器的第n跳 (hop) 地址作为客户端。 ++ `Function`: 自定义的信任函数,第一个参数为 `address` + ```js + function myTrustFn(address, hop) { + return address === '1.2.3.4' || hop === 1 + } + ``` + +更多示例详见 [proxy-addr](https://www.npmjs.com/package/proxy-addr)。 + +你还可以通过原始的 `request` 对象获取 `ip` 与 `hostname` 的值。 + +```js +fastify.get('/', (request, reply) => { + console.log(request.raw.ip) + console.log(request.raw.hostname) +}) +``` + + +### `pluginTimeout` + +单个插件允许加载的最长时间,以毫秒计。如果某个插件加载超时,则 [`ready`](https://github.com/fastify/fastify/blob/master/docs/Server.md#ready) 会抛出一个含有 `'ERR_AVVIO_PLUGIN_TIMEOUT'` 代码的 `Error` 对象。 + ++ 默认值: `0` (禁用状态) + +## 实例 + +### 服务器方法 #### 服务器 -`fastify.server`:由 [**`Fastify 的工厂函数`**](https://github.com/fastify/docs-chinese/blob/master/docs/Factory.md) 生成的 Node 原生 [server](https://nodejs.org/api/http.html#http_class_http_server) 对象。 +`fastify.server`:由 [**`Fastify 的工厂函数`**](https://github.com/fastify/docs-chinese/blob/master/docs/Server.md) 生成的 Node 原生 [server](https://nodejs.org/api/http.html#http_class_http_server) 对象。 #### after