博客
关于我
nodejs koa入门指引
阅读量:128 次
发布时间:2019-02-27

本文共 11523 字,大约阅读时间需要 38 分钟。

目录

环境

  • os: macOS Cataline 10.15.4
  • node:v10.20.0 (node v7.6.0 or higher for ES2015 and async function support)
  • npm:6.14.4
  • koa:2.11.0

1. 介绍

Koa是由Express团队设计的一种新的Web框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。通过利用异步功能,Koa允许您不再使用回调并大大提高错误处理能力,避免回调地狱问题。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。

2. 快速开始

2.1 初始化项目、安装

mkdir koa_testcd koa_testnpm i koa

2.2 创建app.js

const Koa = require('koa');const app = new Koa();app.use(async ctx => {     ctx.body = 'Hello World';});app.listen(3000);

2.3 启动应用

node app.js

浏览器打开http://localhost:3000/,即可看到Hello World

3. 路由

先安装koa-router

npm i koa-router
const Koa = require('koa')const Router = require('koa-router')const app = new Koa()const router =new Router()router.get('/hello', (ctx) => {     ctx.body='Hello World'});app.use(router.routes()).use(router.allowedMethods());app.listen(3000);

4. 获取请求参数

4.1 path

const Koa = require('koa')const Router = require('koa-router')const app = new Koa()const router =new Router()router.get('/hello/:name', (ctx) => {     ctx.body='Hello World'+','+ctx.params.name});app.use(router.routes()).use(router.allowedMethods());app.listen(3000);

浏览器输入

将输出:Hello World,zhangshan

4.2 query

对上一步稍作修改

router.get('/hello', (ctx) => {     ctx.body='Hello World'+','+ctx.query.name});

浏览器输入

将输出:Hello World,zhangshan

对上一步稍作修改

router.get('/hello', (ctx) => {     ctx.body='Hello World'+','+ctx.querystring});

浏览器输入

将输出:Hello World,name=zhangshan&age=18

4.3 body

需要安装一个中间件koa-body

npm i koa-body

提交body里面的数据要用post请求

const Koa = require('koa')const Router = require('koa-router')const bodyParser = require('koa-body')const app = new Koa()const router =new Router()app.use(bodyParser())router.post('/hello', (ctx) => {     console.log('body',ctx.request.body)  ctx.body='Hello World'+','+ctx.request.body.name});app.use(router.routes()).use(router.allowedMethods());app.listen(3000);

我们用postman或用curl模拟请求,

curl -d '{"name":"zhangshan"}' -H "Content-Type: application/json" -X POST http://127.0.0.1:3000/hello

将输出:Hello World,zhangshan

5. 响应数据

5.1 正常

router.post('/hello', (ctx) => {     console.log('body',ctx.request.body)  let res='['+ctx.request.body.name+']'  //status默认值200 可不填  ctx.response.status=200  //ctx.response.body等价于ctx.body  ctx.response.body='Hello World'+','+res;});

发送一个请求

curl -d '{"name":"zhangshan"}' -H "Content-Type: application/json" -X POST http://127.0.0.1:3000/hello

将输出:Hello World,[zhangshan]

5.2 异常

一种是调用ctx.throw方法,另一种直接抛出err

router.post('/hello', (ctx) => {     console.log('body',ctx.request.body)  if(!ctx.request.body.name){   	//ctx.throw(400,'name required'); 等价于下面的 throw err    const err = new Error('name required');    err.status = 400;    //设置为false ,不会显示详细错误信息,这里客户端只显示Bad request    err.expose = true;    throw err  }  let res='['+ctx.request.body.name+']'  ctx.response.status=200  ctx.response.body='Hello World'+','+res;});

我们不传name属性(name修改成name1了),发送一个请求

curl -d '{"name1":"zhangshan"}' -H "Content-Type: application/json" -X POST http://127.0.0.1:3000/hello

将输出:name required,响应状态码为400

也可以直接修改response

router.post('/hello', (ctx) => {     console.log('body',ctx.request.body)  if(!ctx.request.body.name){             ctx.response.status=400          ctx.response.message='Bad Reqeust miss args'          ctx.response.body='name required'          return  }  let res='['+ctx.request.body.name+']'  //status默认值200 可不填  ctx.response.status=200  //ctx.response.body等价于ctx.body  ctx.response.body='Hello World'+','+res;});

将输出:name required,响应状态码为400,响应状态消息Bad Reqeust miss args

6. 全局错误处理

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

7. 常用中间件

7.1 koa-logger

用于打印请求数据

const KoaLogger = require('koa-logger');// access log infoapp.use(KoaLogger((str, args) => {     //Param str is output string with ANSI Color, and you can get pure text with other modules like strip-ansi  //Param args is a array by [format, method, url, status, time, length]  logger.debug(str)}))

eg:

<-- GET /swagger --> GET /swagger 200 1ms 3.86kb

7.2 koa-http-request

用于发送http请求

const koaRequest = require('koa-http-request');app.use(koaRequest({       json: true, //automatically parsing of JSON response    timeout: 3000,    //3s timeout    host: 'www.baidu.com'}));let result = await ctx.get('/'+, {   });console.log(result)

7.3 koa2-swagger-ui

swagger-ui展示,一般还需要其他工具(如swagger-jsdoc)生成openapi json文件

const koaSwagger = require('koa2-swagger-ui');app.use(  koaSwagger({       routePrefix: '/swagger', // host at /swagger instead of default /docs    swaggerOptions: {         url: `/api-docs.json`, // example path to json      hideTopbar: true, // hide swagger top bar    },  }),);

7.4 koa-convert、koa2-cors

跨域设置

const convert = require('koa-convert')const cors = require('koa2-cors')app.use(convert(cors({   	allowMethods: ['GET', 'POST','PUT','DELETE'],    allowHeaders: ['Content-Type', 'Accept'],    origin: function(ctx) {           return '*' // 本地环境    }})))

7.5 koa-compress

gzip压缩

const compress = require('koa-compress')app.use(compress({     threshold: 2048,  flush: require("zlib").Z_SYNC_FLUSH}))

参考手册

Application

app.listen(...) //监听某个端口app.use(function) //使用中间件app.callback()//返回适合http.createServer() 方法以处理请求的回调函数app.keys =   //设置签名的Cookie密钥。app.context  //上下文,可以在上面添加新的属性,以便其他地方引用(增加依赖,反模式)

Context

// app 引用  ctx.app  // 事件  ctx.app.emit  //用于通过中间件、前端视图传递信息  ctx.state  // is a Koa Request  ctx.request;   // is a Koa Response  ctx.response;   //Node's request object.  ctx.req;  //Node's response object.   ctx.res   //set cookie  ctx.cookies.set(name, value, [options])    //get cookie  ctx.cookies.get(name, [options])   //抛出异常,返回错误状态码  ctx.throw([status], [msg], [properties])   // 断言 ,抛出类似于throw()  ctx.assert(value, [status], [msg], [properties])  //要绕过Koa的内置响应处理,可以显式设置ctx.respond = false;。如果要写入原始res对象而不是让Koa为您处理响应,请使用此选项  ctx.respond

Request aliases

ctx.header 			Request header object.ctx.headers 		Set request header object.ctx.method 			Request method.ctx.method= 		Set request method, useful for implementing middleware such as methodOverride().ctx.url 			Get request URL.ctx.url= 			Set request URL, useful for url rewrites.ctx.originalUrl 	Get request original URL.ctx.origin 			Get origin of URL, include protocol and host.ctx.href 			Get full request URL, include protocol, host and url.ctx.path 			Get request pathname.ctx.path= 			Set request pathname and retain query-string when present.ctx.query  			Get parsed query-string, returning an empty object when no query-string is present. Note that this getter does not support nested parsing.ctx.query=  		Set query-string to the given object. Note that this setter does not support nested objects.ctx.querystring  	Get raw query string void of ?.ctx.querystring= 	Set raw query string.ctx.host  			Get host (hostname:port) when present. Supports X-Forwarded-Host when app.proxy is true, otherwise Host is used.ctx.hostname 		Get hostname when present. Supports X-Forwarded-Host when app.proxy is true, otherwise Host is used.ctx.fresh 			Check if a request cache is "fresh", aka the contents have not changed. This method is for cache negotiation between If-None-Match / ETag, and If-Modified-Since and Last-Modified. It should be referenced after setting one or more of these response headers.ctx.stale 			Inverse of request.fresh.ctx.socket			Return the request socket.ctx.protocol 		Return request protocol, "https" or "http". Supports X-Forwarded-Proto when app.proxy is true.ctx.secure 			Shorthand for ctx.protocol == "https" to check if a request was issued via TLS.ctx.ip 				Request remote address. Supports X-Forwarded-For when app.proxy is true.ctx.ips 			When X-Forwarded-For is present and app.proxy is enabled an array of these ips is returned, ordered from upstream -> downstream. When disabled an empty array is returned.ctx.subdomains 		Return subdomains as an array.ctx.is() 			Check if the incoming request contains the "Content-Type" header field, and it contains any of the give mime types. If there is no request body, null is returned. If there is no content type, or the match fails false is returned. Otherwise, it returns the matching content-type.ctx.accepts() 		Check if the given type(s) is acceptable, returning the best match when true, otherwise false. The type value may be one or more mime type string such as "application/json", the extension name such as "json", or an array ["json", "html", "text/plain"].ctx.acceptsEncodings() Check if encodings are acceptable, returning the best match when true, otherwise false. Note that you should include identity as one of the encodings!ctx.acceptsCharsets() Check if charsets are acceptable, returning the best match when true, otherwise false.ctx.acceptsLanguages() Check if langs are acceptable, returning the best match when true, otherwise false.ctx.get() 			Return request header.

Response aliases

ctx.body   			Get response body.ctx.body=  			Set response bodyctx.status 			Get response status. By default, response.status is set to 404 unlike node's res.statusCode which defaults to 200.ctx.status= 		Set response status via numeric codectx.message 		Get response status message. By default, response.message is associated with response.status.ctx.message= 		Set response status message to the given value.ctx.length=  		Set response Content-Length to the given valuectx.length 			Return response Content-Length as a number when present, or deduce from ctx.body when possible, or undefined.ctx.type= 			Set response Content-Type via mime string or file extension.ctx.type 			Get response Content-Type void of parameters such as "charset"ctx.headerSent 		Check if a response header has already been sent. Useful for seeing if the client may be notified on error.ctx.redirect() 		Perform a [302] redirect to url.ctx.attachment() 	Set Content-Disposition to "attachment" to signal the client to prompt for downloadctx.set()  			Set several response header fields with an objectctx.append() 		Append additional header field with value val.ctx.remove() 		Remove header field.ctx.lastModified  	Return the Last-Modified header as a Date, if it exists.ctx.lastModified= 	Set the Last-Modified header as an appropriate UTC string. You can either set it as a Date or date string.ctx.etag= 			Set the ETag of a response including the wrapped "s. Note that there is no corresponding response.etag getter.

Status code

100 "continue"101 "switching protocols"102 "processing"200 "ok"201 "created"202 "accepted"203 "non-authoritative information"204 "no content"205 "reset content"206 "partial content"207 "multi-status"208 "already reported"226 "im used"300 "multiple choices"301 "moved permanently"302 "found"303 "see other"304 "not modified"305 "use proxy"307 "temporary redirect"308 "permanent redirect"400 "bad request"401 "unauthorized"402 "payment required"403 "forbidden"404 "not found"405 "method not allowed"406 "not acceptable"407 "proxy authentication required"408 "request timeout"409 "conflict"410 "gone"411 "length required"412 "precondition failed"413 "payload too large"414 "uri too long"415 "unsupported media type"416 "range not satisfiable"417 "expectation failed"418 "I'm a teapot"422 "unprocessable entity"423 "locked"424 "failed dependency"426 "upgrade required"428 "precondition required"429 "too many requests"431 "request header fields too large"500 "internal server error"501 "not implemented"502 "bad gateway"503 "service unavailable"504 "gateway timeout"505 "http version not supported"506 "variant also negotiates"507 "insufficient storage"508 "loop detected"510 "not extended"511 "network authentication required"

转载地址:http://pfib.baihongyu.com/

你可能感兴趣的文章
ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
查看>>
ngrok内网穿透可以实现资源共享吗?快解析更加简洁
查看>>
NHibernate学习[1]
查看>>
NHibernate异常:No persister for的解决办法
查看>>
NIFI1.21.0_java.net.SocketException:_Too many open files 打开的文件太多_实际操作---大数据之Nifi工作笔记0051
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_补充_更新时如果目标表中不存在记录就改为插入数据_Postgresql_Hbase也适用---大数据之Nifi工作笔记0059
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>
NIFI1.21.0最新版本安装_连接phoenix_单机版_Https登录_什么都没改换了最新版本的NIFI可以连接了_气人_实现插入数据到Hbase_实际操作---大数据之Nifi工作笔记0050
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_插入修改删除增量数据实时同步_通过分页解决变更记录过大问题_01----大数据之Nifi工作笔记0053
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表或全表增量同步_实现指定整库同步_或指定数据表同步配置_04---大数据之Nifi工作笔记0056
查看>>
NIFI1.23.2_最新版_性能优化通用_技巧积累_使用NIFI表达式过滤表_随时更新---大数据之Nifi工作笔记0063
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_生成插入Sql语句_实际操作02---大数据之Nifi工作笔记0041
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_不带分页处理_01_QueryDatabaseTable获取数据_原0036---大数据之Nifi工作笔记0064
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_无分页功能_02_转换数据_分割数据_提取JSON数据_替换拼接SQL_添加分页---大数据之Nifi工作笔记0037
查看>>