博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nodejs koa入门指引
阅读量:126 次
发布时间:2019-02-27

本文共 11543 字,大约阅读时间需要 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/

你可能感兴趣的文章