ABCDdouyaer / jiraiya.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

koa2基本用法

ABCDdouyaer opened this issue · comments

koa2基本用法

koa是由express的幕后原班人马打造的基于Node.js平台的下一代web开发框架,致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。

koa的优点

  • 摒弃了express的callback写法,采用Async新特性,使代码看起来更加优雅简洁;
  • 是一个不绑定任何中间件的干干净净的裸框架,如果说express是大而全,那么koa就是小而精;
  • 对stream的支持度很高,并且对错误处理更加友好。

koa的安装

Koa 依赖 node v7.6.0 或 ES2015及更高版本和 async 方法支持.

你可以使用自己喜欢的版本管理器快速安装支持的 node 版本:

nvm install 7

npm i koa

node my-koa-app.js

koa的基本用法

必修的 hello world 应用:

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

Koa 中间件以更传统的方式级联,Koa 调用“下游”,然后控制流回“上游”,接收到请求首先执行1号中间件,遇到next()暂停当前中间件,继续执行2号中间件,2号执行遇到next()暂停执行,执行3号中间件,执行完3号以冒泡的形式回流到上游,依次执行2号和1号未执行完的部分

const Koa = require('koa')
const app = new Koa()

//1号
app.use(async(ctx, next)=>{

    ctx.body = `<span>1号→</span>`;
    await next();
    ctx.body += `<span>5号</span>`;
})
//2号
app.use(async(ctx, next)=>{
    ctx.body += `<span>2号→</span>`;
    await next();
    ctx.body += `<span>4号→</span>`;
})
//3号
app.use(async(ctx, next)=>{
    ctx.body += `<span>3号→</span>`;
})

app.listen(8080, ()=>{
    console.log('server is running...')
})

执行结果:1号→2号→3号→4号→5号

app.listen(...)

这里的 app.listen(port, callback) 方法只是以下方法的语法糖:

const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(port, callback);

这意味着您可以将同一个应用程序同时作为 HTTP 和 HTTPS 或多个地址:

const Koa = require('koa')
const app = new Koa()
const https = require('https');
const http = require('http');

app.use(async(ctx, next)=>{
    ctx.body = `<h1>Hello World!</h1>`;
})


http.createServer(app.callback()).listen(8080);
http.createServer(app.callback()).listen(8081);
// https.createServer(app.callback()).listen(8080);

app.callback()

返回适用于 http.createServer() 方法的回调函数来处理请求。你也可以使用此回调函数将 koa 应用程序挂载到 Connect/Express 应用程序中。

const express = require('express');
const server = express();
const koa = require('koa');
const app = new koa();

app.use(async(ctx, next)=>{
    ctx.body ='hello world!'
})

server.get('/', app.callback()).listen(8080)

app.use(function)

将给定的中间件方法添加到此应用程序。中间件列表:https://github.com/koajs/koa/wiki#middleware

app.keys=

设置签名的 Cookie 密钥。

例如,以下是可以接受的:

app.keys = ['im a newer secret', 'i like turtle'];
app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256');
const Koa = require('koa')
const app = new Koa()

app.keys = ['im a newer secret', 'i like turtle'];

app.use(async(ctx, next)=>{
    if(ctx.cookies.get('name')){
        console.log(ctx.cookies.get('name'))
    }else{
        ctx.cookies.set('name', 'tobi', { signed: true });
    }   
    ctx.body = `<h1>Hello World!</h1>`;
}).listen(8080)

app.context

context是ctx的原型,可以在其上面挂在一些方法或者属性

例如,要从 ctx 添加对数据库的引用:

app.context.db = db();

app.use(async ctx => {
  console.log(ctx.db);
});

错误处理

默认情况下将错误通过process.stderr输出到终端,需要自行处理错误,例如打印错误日志,可以添加一个‘error’的事件侦听器

app.on('error', err => {
  log.error('server error', err)
});

context上面挂载的方法和属性

  • request:Node的request对象
API 作用
request.header/request.headers 获取请求头部
request.header=/request.headers= 设置请求标头部
request.method 设置方法
request.length 以数字返回请求的 Content-Length,或 undefined
request.url 获取请求的url
request.originalUrl 获取请求的原始url
request.url= 设置请求 URL, 对 url 重写有用
request.origin 获取URL的来源,包括 protocol 和 host
request.href 获取完整的URL,包括 protocol 和 host以及参数
request.path 获取请求路径名
request.path= 设置请求路径名,并在存在时保留查询字符串
request.querystring 根据 ? 获取原始查询字符串
request.querystring= 设置原始查询字符串
request.search 使用?原始查询字符串
request.search= 设置原始查询字符串
request.host 获取当前主机{hostname:port}
request.hostname 获取主机名
request.URL 获取WHATWG解析的URL对象
request.type 获取请求的Content-Type
request.charset 在存在时获取请求字符集,或者undefined
request.query 获取解析的查询字符串对象,没有查询字符串的时候返回空对象
request.query= 将查询字符串设置为给定对象
request.fresh 检查请求的缓存内容是否没有更改,返回boolean
request.stale 检查请求的缓存内容是否被更改,返回boolean
request.protocol 返回请求的协议
request.secure 通过 ctx.protocol == "https" 来检查请求是否通过 TLS 发出
request.ip 请求远程地址
request.ips 当 X-Forwarded-For 存在并且 app.proxy 被启用时,这些 ips 的数组被返回,从上游 - >下游排序。 禁用时返回一个空数组
request.subdomains 将子域返回为数组
request.is(types...) 检查传入请求是否包含 Content-Type 头字段, 并且包含任意的 mime type。如果没有请求主体,返回 null。 如果没有内容类型,或者匹配失败,则返回 false。 反之则返回匹配的 content-type。
request.accepts(types) 检查给定的 type(s) 是否可以接受,如果 true,返回最佳匹配,否则为 false。 type 值可能是一个或多个 mime 类型的字符串,如 application/json,扩展名称如 json,或数组 ["json", "html", "text/plain"]。
request.acceptsEncodings(encodings) 检查 encodings 是否可以接受,返回最佳匹配为 true,否则为 false。 请注意,您应该将identity 作为编码之一!
request.acceptsCharsets(charsets) 检查 charsets 是否可以接受,在 true 时返回最佳匹配,否则为 false。
request.acceptsLanguages(langs) 检查 langs 是否可以接受,如果为 true,返回最佳匹配,否则为 false。
request.idempotent 检查请求是否是幂等的。
request.socket 返回请求套接字
request.get(field) 返回请求标头
  • response:Node的reponse对象
API 作用
response.header/response.headers 响应标头对象
response.socket 请求套接字
response.status 获取响应状态
response.status= 设置响应状态(响应状态查看附表)
response.message 获取响应的状态消息
response.message= 将响应的状态消息设置为给定值
response.length= 将响应的 Content-Length 设置为给定值
response.length 以数字返回响应的 Content-Length
response.body 获取响应主体
response.body= 将响应主体设置为string/Buffer/Stream/Object||ArrayJSON-字符串化/null无内容响应
response.get(field) 不区分大小写获取响应标头字段值 field
response.set(field,value) 设置响应头部field到value
response.append(field, value) 用值 val 附加额外的标头 field
response.set(fields) 用一个对象设置多个响应标头fields
response.remove(field) 删除标头 field
response.type 获取响应 Content-Type 不含参数 "charset"
response.type= 设置响应 Content-Type 通过 mime 字符串或文件扩展名
response.is(types...) 非常类似 ctx.request.is(). 检查响应类型是否是所提供的类型之一。这对于创建操纵响应的中间件特别有用
response.redirect(url, [alt]) 执行 [302] 重定向到 url
response.attachment([filename]) 将 Content-Disposition 设置为 “附件” 以指示客户端提示下载。(可选)指定下载的 filename。
response.headerSent 检查是否已经发送了一个响应头。 用于查看客户端是否可能会收到错误通知
response.lastModified 将 Last-Modified 标头返回为 Date, 如果存在
response.lastModified= 将 Last-Modified 标头设置为适当的 UTC 字符串。您可以将其设置为 Date 或日期字符串。
response.etag= 设置包含 " 包裹的 ETag 响应, 请注意,没有相应的 response.etag getter
response.vary(field) 在 field 上变化
response.flushHeaders() 刷新任何设置的标头,并开始主体
响应状态码
100 continue 307 temporary redirect 417 expectation failed
101 switching protocols 308 permanent redirect 418 I'm a teapot
102 processing 400 bad request 422 unprocessable entity
200 ok 401 unauthorized 423 locked
201 created 402 payment required 424 failed dependency
202 accepted 403 forbidden 426 upgrade required
203 non-authoritative information 404 not found 428 precondition required
204 no content 405 method not allowed 429 too many requests
205 reset content 406 not acceptable 431 request header fields too large
206 partial content 407 proxy authentication required 500 internal server error
207 multi-status 408 request timeout 501 not implemented
208 already reported 409 conflict 502 bad gateway
226 im used 410 gone 503 service unavailable
300 multiple choices 411 length required 504 gateway timeout
301 moved permanently 412 precondition failed 505 http version not supported
302 found 413 payload too large 506 variant also negotiates
303 see other 414 uri too long 507 insufficient storage
304 not modified 415 unsupported media type 508 loop detected
305 use proxy 416 range not satisfiable 510 not extended
511 network authentication required
  • state:配置全局变量,ctx.state配置的全局变量我们不仅可以在其他的路由页面使用,我们还可以在全局模板使用.

  • app:应用程序实例引用

  • cookies.get(name, [options]):用于获取cookie值

  • cookies.set(name, value, [options]):设置cookie,下面是options

    • maxAge 一个数字表示从 Date.now() 得到的毫秒数
    • signed cookie 签名值
    • expires cookie 过期的 Date
    • path cookie 路径, 默认是'/'
    • domain cookie 域名
    • secure 安全 cookie
    • httpOnly 服务器可访问 cookie, 默认是 true
    • overwrite 一个布尔值,表示是否覆盖以前设置的同名的 cookie (默认是 false). 如果是 true, 在同一个请求中设置相同名称的所有 Cookie(不管路径或域)是否在设置此Cookie 时从 Set-Cookie 标头中过滤掉。
  • throw([status], [msg], [properties]):用于抛出服务器错误,默认为500

  • ctx.assert(value, [status], [msg], [properties]):当 !value 时,Helper 方法抛出类似于 .throw() 的错误。

  • respond:为了绕过 Koa 的内置 response 处理,你可以显式设置 ctx.respond = false;。 如果您想要写入原始的 res 对象而不是让 Koa 处理你的 response,请使用此参数。

官方文档地址:https://koa.bootcss.com