feat: add koajs.md sheatsheet.

This commit is contained in:
jaywcjlove 2022-10-18 23:36:25 +08:00
parent 227a7a7149
commit 5685eb285a
4 changed files with 427 additions and 0 deletions

View File

@ -47,6 +47,7 @@ Quick Reference
## Nodejs
[Express.js](./docs/expressjs.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
[Koa.js](./docs/koajs.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
<!--rehype:class=home-card-->
## 工具

424
docs/koajs.md Normal file
View File

@ -0,0 +1,424 @@
Koajs 备忘清单
===
基于 Node.js 平台的下一代 web 开发框架,包含 [Koa](https://koajs.com/) 的 API 参考列表和一些示例。
入门
---
### Hello World
<!--rehype:wrap-class=row-span-2-->
[Koa](https://koajs.com/) 需要 [node v7.6.0](https://nodejs.org) 或更高版本来支持ES2015、异步方法你可以安装自己支持的 `node` 版本
- 安装依赖
```bash
$ mkdir myapp # 创建目录
$ cd myapp # 进入目录
$ nvm install 7
$ npm init -y # 初始化一个配置
$ npm install koa # 安装依赖
```
- 入口文件 `index.js` 添加代码:
```js
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
```
- 使用以下命令运行应用程序
```bash
$ node index.js
```
<!--rehype:className=style-timeline-->
### 级联
<!--rehype:wrap-class=row-span-2-->
```js
const Koa = require('koa');
const app = new Koa();
// X-Response-Time x 响应时间
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
});
// 记录器 logger
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(
`${ctx.method} ${ctx.url} - ${ms}`
);
});
// 响应 response
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
```
### 配置
:- | :-
:- | :-
`app.env` | 默认为 `NODE_ENV``development`
`app.keys` | 签名 `cookie` 密钥数组
`app.proxy` | 何时信任真正的代理头字段
`app.subdomainOffset` | 要忽略的 `.subdomains` 的偏移量,默认为 `2`
`app.proxyIpHeader` | 代理 `ip` 头,默认为 `X-Forwarded-For`
`app.maxIpsCount` | 从代理 `ip` 头读取的最大 `ips` 数,默认为 `0`(表示无穷大)
<!--rehype:className=style-list style-list-arrow-->
### app.callback()
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`app.listen(...)` [#](https://koajs.com/#app-listen-) | 为一个绑定 `3000` 端口的简单 `Koa` 应用
`app.callback()` [#](https://koajs.com/#app-callback-) | 返回一个适合 `http.createServer()` 方法的回调函数用来处理请求
`app.use(function)` [#](https://koajs.com/#app-use-function-) | 添加指定的中间件,详情请看 [Middleware](https://github.com/koajs/koa/wiki#middleware)
`app.keys` [#](https://koajs.com/#app-keys-) | 设置签名 `cookie` 密钥
`app.context` [#](https://koajs.com/#app-context) | 从中创建 `ctx` 的原型
<!--rehype:className=style-list style-list-arrow-->
### 错误处理
```js
app.on('error', (err, ctx) => {
log.error('server error', err, ctx)
});
```
默认情况下 `Koa` 会将所有错误信息输出到 `stderr` 除非 `app.silent``true`。当 `err.status``404` 或者 `err.expose` 时,默认错误处理程序也不会输出错误
### Context 示例
```js
app.use(async ctx => {
ctx; // 这是上下文 Context
ctx.request; // 这是 koa Request
ctx.response; // 这是 koa Response
});
```
### app.listen(...)
<!--rehype:wrap-class=col-span-2 row-span-2-->
```js
const Koa = require('koa');
const app = new Koa();
app.listen(3000);
```
`app.listen(...)` 实际上是以下代码的语法糖:
```js
const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
```
这意味着您可以同时支持 `HTTPS``HTTPS`,或者在 `多个端口` 监听同一个应用
```js
const http = require('http');
const https = require('https');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001);
```
### ctx.throw 示例
```js
ctx.throw(400);
ctx.throw(400, 'name required');
ctx.throw(400, 'name required', { user: user });
```
`this.throw('name required', 400)` 等价于
```js
const err = new Error('name required');
err.status = 400;
err.expose = true;
throw err;
```
### ctx.assert 示例
```js
ctx.assert(
ctx.state.user,
401,
'User not found. Please login!'
);
```
### Context(上下文) API
<!--rehype:wrap-class=col-span-2-->
:- | :-
:- | :-
`ctx.req` | Node 的 request 对象
`ctx.res` | Node 的 response 对象
`ctx.request` | Koa 的 Request 对象
`ctx.response` | Koa 的 Response 对象
`ctx.state` | 推荐的命名空间,用于通过中间件传递信息到前端视图
`ctx.app` | 应用实例引用
`ctx.app.emit` | 发出由第一个参数定义的类型的事件
`ctx.cookies.get(name, [options])` | 获得 `cookie` 中名为 `name` 的值
`ctx.cookies.set(name, value, [options])` | 设置 `cookie` 中名为 `name` 的值
`ctx.throw([status], [msg], [properties])` | 抛出包含 `.status` 属性的错误,默认为 `500`
`ctx.assert(value, [status], [msg], [properties])` | 当 `!value` 时, `Helper` 方法抛出一个类似 `.throw()` 的错误
`ctx.respond` | 避免使用 `Koa` 的内置响应处理功能,您可以直接赋值 `this.repond = false`
<!--rehype:className=style-list style-list-arrow-->
### ctx.cookies.set 参数
:- | :-
:- | :-
`maxAge` | 表示从Date开始的毫秒数 `now()` 到期。
`expires` | 一个 `Date` 对象,指示 `cookie` 的到期日期(默认情况下在会话结束时到期)
`path` | 表示 `cookie` 路径的字符串(默认为`/`
`domain` | 表示 `cookie` 的域的字符串(无默认值)
`secure` | 一个布尔值,指示 `cookie` 是否只通过HTTPS发送HTTP默认为falseHTTPS默认为true。阅读有关此选项的更多信息
`httpOnly` | 一个布尔值指示cookie是否只通过HTTPS发送而不可用于客户端 JavaScript默认为true
`sameSite` | 一个布尔值或字符串指示cookie是否为“同一站点”cookie默认为false。这可以设置为“strict”、“lax”、“none”或true映射为“strect”
`signed` | 一个布尔值指示是否对cookie进行签名默认为false。如果这是真的还将发送另一个附加了.sig后缀的同名cookie其中一个27字节的url安全base64 SHA1值表示cookie name=cookie值相对于第一个Keygrip键的哈希值。此签名密钥用于在下次收到cookie时检测篡改
`overwrite` | 一个布尔值,指示是否覆盖以前设置的同名 `cookie`默认为false。如果为true则在设置此Cookie时将从set-Cookie标头中筛选出在同一请求期间设置的具有相同名称的所有Cookie无论路径或域如何
<!--rehype:className=style-list style-list-arrow-->
### 请求(Request)
<!--rehype:wrap-class=row-span-5-->
:- | :-
:- | :-
`request.header` | 请求头对象
`request.header=` | 设置请求头对象
`request.headers` | 请求头对象。等价于 request.header.
`request.headers=` | 设置请求头对象。 等价于request.header=.
`request.method` | 请求方法
`request.method=` | 设置请求方法, 在实现中间件时非常有用,比如 methodOverride()
`request.length` | 以数字的形式返回 request 的内容长度(Content-Length),或者返回 undefined。
`request.url` | 获得请求url地址.
`request.url=` | 设置请求地址用于重写url地址时
`request.originalUrl` | 获取请求原始地址
`request.origin` | 获取URL原始地址, 包含 protocol 和 host
`request.href` | 获取完整的请求URL, 包含 protocol, host 和 url
`request.path` | 获取请求路径名
`request.path=` | 设置请求路径名并保留当前查询字符串
`request.querystring` | 获取查询参数字符串(url中?后面的部分),不包含?
`request.querystring=` | 设置原始查询字符串
`request.search` | 获取查询参数字符串,包含?
`request.search=` | 设置原始查询字符串
`request.host` | 获取 host (hostname:port)。 当 app.proxy 设置为 true 时,支持 X-Forwarded-Host
`request.hostname` | 获取 hostname。当 app.proxy 设置为 true 时,支持 X-Forwarded-Host。
`request.URL` | 获取 WHATWG 解析的对象.
`request.type` | 获取请求 Content-Type不包含像 "charset" 这样的参数。
`request.charset` | 获取请求 charset没有则返回 `undefined`
`request.query` | 将查询参数字符串进行解析并以对象的形式返回,如果没有查询参数字字符串则返回一个空对象
`request.query=` | 根据给定的对象设置查询参数字符串
`request.fresh` | 检查请求缓存是否 "fresh"(内容没有发生变化)
`request.stale` | 与 req.fresh 相反
`request.protocol` | 返回请求协议,"https" 或者 "http"
`request.secure` | 简化版 this.protocol == "https",用来检查请求是否通过 TLS 发送
`request.ip` | 请求远程地址,当 app.proxy 设置为 true 时,支持 X-Forwarded-Host
`request.ips` | 当 X-Forwarded-For 存在并且 app.proxy 有效,将会返回一个有序(从 upstream 到 downstreamip 数组
`request.subdomains` | 以数组形式返回子域名
`request.is(types...)` | 检查请求所包含的 "Content-Type" 是否为给定的 type 值
`request.accepts(types)` | 检查给定的类型 types(s) 是否可被接受,当为 true 时返回最佳匹配,否则返回 false
`request.acceptsEncodings(encodings)` | 检查 `encodings` 是否可以被接受,当为 `true` 时返回最佳匹配,否则返回 `false`
`request.acceptsCharsets(charsets)` | 检查 `charsets` 是否可以被接受,如果为 `true` 则返回最佳匹配,否则返回 `false`
`request.acceptsLanguages(langs)` | 检查 `langs` 是否可以被接受,如果为 `true` 则返回最佳匹配,否则返回 `false`
`request.idempotent` | 检查请求是否为幂等(idempotent)
`request.socket` | 返回请求的socket
`request.get(field)` | 返回请求头
<!--rehype:className=style-list style-list-arrow-->
### 响应(Response)
<!--rehype:wrap-class=row-span-2-->
:- | :-
:- | :-
`response.header` | Response header 对象
`response.headers` | Response header 对象。等价于 response.header.
`response.socket` | Request socket.
`response.status` | 获取响应状态。 默认情况下response.status设置为404而不像node's res.statusCode默认为200。
`response.status=` | 通过数字设置响应状态
`response.message` | 获取响应状态消息。默认情况下, response.message关联response.status。
`response.message=` | 将响应状态消息设置为给定值。
`response.length=` | 将响应Content-Length设置为给定值。
`response.length` | 如果 Content-Length 作为数值存在,或者可以通过 ctx.body 来进行计算,则返回相应数值,否则返回 undefined。
`response.body` | 获取响应体。
`response.body=` | 设置响应体为如 `string`,`Buffer`,`Stream`,`Object\|Array`,`null`
`response.get(field)` | 获取 response header 中字段值field 不区分大小写
`response.set(field, value)` | 设置 response header 字段 field 的值为 value
`response.append(field, value)`| 添加额外的字段field 的值为 val
`response.set(fields)` | 使用对象同时设置 response header 中多个字段的值
`response.remove(field)` | 移除 response header 中字段 filed
`response.type` | 获取 response Content-Type不包含像"charset"这样的参数
`response.type=` | 通过 mime 类型的字符串或者文件扩展名设置 response Content-Type
`response.is(types...)` | 跟 `ctx.request.is()` 非常类似。用来检查响应类型是否是所提供的类型之一
`response.redirect(url, [alt])` | 执行 [302] 重定向到对应 url
`response.attachment([filename])` | 设置 "attachment" 的 Content-Disposition用于给客户端发送信号来提示下载
`response.headerSent` | 检查 response header 是否已经发送,用于在发生错误时检查客户端是否被通知。
`response.lastModified` | 如果存在 Last-Modified则以 Date 的形式返回。
`response.lastModified=` | 以 UTC 格式设置 Last-Modified。您可以使用 Date 或 date 字符串来进行设置。
`response.etag=` | 设置 包含 "s 的 ETag
`response.vary(field)` | 不同于field.
`response.flushHeaders()` | 刷新任何设置的响应头,并开始响应体
<!--rehype:className=style-list style-list-arrow-->
### 请求(Request)别名
以下访问器和别名与 [Request](#请求request) 等价:
- `ctx.header`
- `ctx.headers`
- `ctx.method`
- `ctx.method=`
- `ctx.url`
- `ctx.url=`
- `ctx.originalUrl`
- `ctx.origin`
- `ctx.href`
- `ctx.path`
- `ctx.path=`
- `ctx.query`
- `ctx.query=`
- `ctx.querystring`
- `ctx.querystring=`
- `ctx.host`
- `ctx.hostname`
- `ctx.fresh`
- `ctx.stale`
- `ctx.socket`
- `ctx.protocol`
- `ctx.secure`
- `ctx.ip`
- `ctx.ips`
- `ctx.subdomains`
- `ctx.is()`
- `ctx.accepts()`
- `ctx.acceptsEncodings()`
- `ctx.acceptsCharsets()`
- `ctx.acceptsLanguages()`
- `ctx.get()`
### 响应(Response)别名
以下访问器和别名与 [Response](#响应response) 等价:
- `ctx.body`
- `ctx.body=`
- `ctx.status`
- `ctx.status=`
- `ctx.message`
- `ctx.message=`
- `ctx.length=`
- `ctx.length`
- `ctx.type=`
- `ctx.type`
- `ctx.headerSent`
- `ctx.redirect()`
- `ctx.attachment()`
- `ctx.set()`
- `ctx.append()`
- `ctx.remove()`
- `ctx.lastModified=`
- `ctx.etag=`
### request.fresh 示例
```js
// freshness 检查需要状态 20x 或 304
ctx.status = 200;
ctx.set('ETag', '123');
// 缓存正常
if (ctx.fresh) {
ctx.status = 304;
return;
}
// 缓存已过时
// 获取新数据
ctx.body = await db.find('something');
```
### ctx.is 示例
```js
// Content-Type: text/html; charset=utf-8
ctx.is('html'); // => 'html'
ctx.is('text/html'); // => 'text/html'
ctx.is('text/*', 'text/html');
// => 'text/html'
// 当 Content-Type 为 application/json 时
ctx.is('json', 'urlencoded'); // => 'json'
ctx.is('application/json');
// => 'application/json'
ctx.is('html', 'application/*');
// => 'application/json'
ctx.is('html'); // => false
```
### ctx.accepts 示例
```js
// 接受: text/*, application/json
ctx.accepts('html');
// => "html"
ctx.accepts('text/html');
// => "text/html"
ctx.accepts('json', 'text');
// => "json"
ctx.accepts('application/json');
// => "application/json"
```
### request.acceptsCharsets 示例
```js
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
ctx.acceptsCharsets('utf-8', 'utf-7');
// => "utf-8"
ctx.acceptsCharsets(['utf-7', 'utf-8']);
// => "utf-8"
```
检查 `charsets` 是否可以被接受,如果为 `true` 则返回最佳匹配, 否则返回 `false`
### response.set 示例
```js
ctx.set({
'Etag': '1234',
'Last-Modified': date
});
```
使用对象同时设置 response header 中多个字段的值
### response.type 示例
```js
const ct = ctx.type;
// => "image/png"
```
获取 response Content-Type不包含像"charset"这样的参数

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 230 230" height="1em" width="1em"><path d="M176.09375,0 C205.86535,-5.46895416e-15 230,24.1346502 230,53.90625 L230,176.09375 C230,205.86535 205.86535,230 176.09375,230 L53.90625,230 C24.1346502,230 3.64596944e-15,205.86535 0,176.09375 L0,53.90625 C-3.64596944e-15,24.1346502 24.1346502,5.46895416e-15 53.90625,0 L176.09375,0 Z M96.3915625,71.8417578 C72.1633984,52.8083594 36.9455469,65.5976172 28.3034766,96.3196875 C26.8542969,101.414727 26.205625,106.860156 25.15625,111.855469 C25.15625,114.753001 25.1735062,117.650508 25.2065625,120.547852 C25.5560547,122.146172 26.205625,123.845117 26.205625,125.543164 C27.040801,136.25108 31.3566466,146.391645 38.4944531,154.417148 C53.2945034,168.337492 75.3687421,171.159676 93.1949219,161.410586 C103.851236,155.025409 110.993734,144.108874 112.576914,131.787305 C107.831367,130.339023 105.333711,131.188047 103.784805,136.183359 C101.384533,146.161673 94.1154179,154.257423 84.4522266,157.714414 C55.1290234,167.505586 32.2,148.323047 33.4991406,116.551602 L113.426836,116.551602 C114.12582,98.7679297 110.578789,82.9823828 96.3915625,71.8417578 Z M134.6075,70.6917578 C131.648507,65.8588504 125.699893,63.7717491 120.369961,65.6964453 L156.287695,112.505039 L117.672852,164.308047 C122.86047,166.177143 128.629968,163.911928 131.160195,159.012656 C140.551562,145.274648 150.842266,132.03707 161.132969,118.249648 L164.880352,123.244961 C173.522422,135.133984 182.513984,146.773242 190.656523,158.962344 C193.339516,164.091123 199.430792,166.407513 204.84375,164.357461 C192.654648,148.072383 180.815937,132.187109 168.876602,116.35125 C167.81759,115.403944 167.212286,114.050351 167.212286,112.629473 C167.212286,111.208595 167.81759,109.855001 168.876602,108.907695 C175.370508,100.864883 181.514922,92.5723047 187.759062,84.3300391 L201.696523,65.8464844 C196.612958,63.8698897 190.855156,66.0182947 188.308906,70.8417969 C179.766562,82.9311719 170.624961,94.6207422 161.382734,106.860156 C152.191719,94.5210156 142.949492,82.8817578 134.6075,70.6917578 Z M70.8691642,70.1898981 L71.5147266,70.1940234 C90.8967188,70.3431641 105.433437,86.6785547 105.883555,109.707305 L33.5988672,109.707305 L33.5485547,109.607578 C34.4982031,85.8789453 49.9342578,69.8939453 71.5147266,70.1940234 Z"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

1
scripts/assets/koajs.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="1em" height="1em" viewBox="0 0 230 230"><path d="M176.09375,0 C205.86535,-5.46895416e-15 230,24.1346502 230,53.90625 L230,176.09375 C230,205.86535 205.86535,230 176.09375,230 L53.90625,230 C24.1346502,230 3.64596944e-15,205.86535 0,176.09375 L0,53.90625 C-3.64596944e-15,24.1346502 24.1346502,5.46895416e-15 53.90625,0 L176.09375,0 Z M46.6655391,74 L39,74 L39,156 L46.6655391,156 L46.6655391,129.650518 L49.6224434,126.261287 L69.8814961,156 L77.547334,156 L54.002666,121.450727 L71.8528652,101.333433 L70.7576602,101.333433 L46.6655391,128.447878 L46.6655391,74 Z M166.63517,101.605824 C155.279402,101.605824 148.80559,105.323536 147.426199,105.960807 L147.850535,106.70429 C150.50383,105.217325 158.675584,102.455817 165.255779,102.455817 C175.471142,102.455817 176.406034,109.037681 176.428332,111.278315 L176.428388,111.441925 C176.424978,111.802842 176.39908,112.014881 176.39908,112.014881 L176.39908,129.646341 C175.125475,129.54013 169.7131,129.327706 164.937229,129.752553 C146.046211,131.027095 143.499299,136.337984 144.560438,143.454176 C145.19724,147.702947 147.319816,155.562622 159.737021,155.562622 C170.24352,155.562622 174.276504,149.933396 176.39908,146.10977 L176.39908,147.596736 C176.39908,147.596736 176.396486,147.62746 176.394995,147.684985 L176.394581,147.834611 C176.41733,149.115868 177.139684,155.137775 188.709902,155.137775 L192,155.137476 L192,154.287782 L188.70601,154.287921 C188.703429,154.288003 188.699579,154.288109 188.694503,154.288209 L188.616885,154.288028 C187.942429,154.274794 183.828246,153.934323 183.828246,147.596437 L183.828246,112.015179 C183.828246,108.403679 182.023922,101.605824 166.63517,101.605824 Z M111.11141,101.498121 C96.1873359,101.498121 84.7236914,111.37582 84.7236914,129.113791 C84.7236914,148.44464 96.5115645,155.45462 110.246303,155.45462 C125.170377,155.45462 136.634021,145.576921 136.634021,127.839249 C136.634021,108.508101 124.846148,101.498121 111.11141,101.498121 Z M164.943803,130.353127 C170.178674,129.705713 175.099477,130.137422 176.356049,130.245125 L176.356049,143.304406 C176.041682,147.621499 169.550537,154.852853 161.593939,154.852853 C154.26518,154.852853 152.694838,148.700921 152.275881,143.412408 C151.647744,135.533639 153.846521,131.648255 164.943803,130.353127 Z M111.117088,102.20789 C121.305932,102.20789 129.523107,109.148952 129.523107,127.835669 C129.523107,144.920854 120.97752,154.744851 110.240625,154.744851 C100.051482,154.744851 91.8346055,147.804087 91.8346055,129.117072 C91.8346055,112.031887 100.380193,102.20789 111.117088,102.20789 Z"/></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB