koa初见

作者: 范小饭_ | 来源:发表于2019-07-23 14:39 被阅读0次
    image

    今天学一下koa,之所以在express,koa,egg中选择koa,仅仅是因为我觉得koa的官网好看,看上去很简洁,就好像只要学了文档主要的几个对象就可以通吃了一样​。

    Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。

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

    一、安装

    $ nvm install 7
    

    让我们和koa的世界say个hi

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

    [图片上传失败...(image-557293-1563610308704)]

    二、 koa实例:app

    app.listen(...):程序挂在的端口
    app.use(function):将给定的中间件方法添加到此应用程序
    app.keys= :设置签名的 Cookie 密钥。
    app.context:app.context
    错误处理:app.on('error', err => { log.error('server error', err) });

    三、context

    Koa Context 将 node 的 request 和 response 对象封装到单个对象中,表示一次请求的上下文,每个请求都将创建一个 Context,并在中间件中作为接收器引用,或者 ctx 标识符。

    我们可以打印一下context对象

    const Koa = require('koa');
    
    image

    ctx.req:Node 的 request 对象.
    ctx.res:Node 的 response 对象.
    ctx.request:koa 的 Request 对象.
    ctx.response: koa 的 Response 对象.
    ctx.state: 推荐的命名空间,用于通过中间件传递信息和你的前端视图。
    ctx.state.user = await User.find(id);
    ctx.app: 应用程序实例引用
    ctx.cookies.get(name, [options]) :通过 options 获取 cookie name:
    ctx.cookies.set(name, value, [options]) :通过 options 设置 cookie name 的 value :
    ctx.throw([status], [msg], [properties])**: 抛出错误

    因为ctx表示一个请求的上下文,所以当然它可以直接访问到request和response的属性

    ctx的某些访问器和 Request 别名 和 Response 别名等效
    ctx.header = request.header
    ctx.headers = request.headers
    ctx.method = request.method
    ...
    ctx.body = response.body
    ctx.status = response.status
    ctx.message = response.message

    四、Request对象

    常用Request对象属性
    request.header:请求标头对象
    request.method:请求方法
    request.length:返回以数字返回请求的 Content-Length,或 undefined
    request.url:获取请求 URL.
    request.originalUrl:获取请求原始URL。
    request.origin:获取URL的来源,包括 protocol 和 host。
    request.href:获取完整的请求URL,包括 protocol,host 和 url。
    request.path:请求路径
    request.querystring:设置原始查询字符串。
    request.search:使用 ? 获取原始查询字符串。
    request.host:获取当前主机(hostname:port)。当 app.proxy 是 true 时支持 X-Forwarded-Host,否则使用 Host。
    request.hostname:存在时获取主机名。当 app.proxy 是 true 时支持 X-Forwarded-Host,否则使用 Host。
    request.URL:获取 WHATWG 解析的 URL 对象。
    request.type:获取请求 Content-Type 不含参数 "charset"。
    request.charset:在存在时获取请求字符集,或者 undefined:
    request.query:获取解析的查询字符串, 当没有查询字符串时,返回一个空对象。请注意,此 getter 支持嵌套解析。
    request.fresh:检查请求缓存是否“新鲜”,也就是内容没有改变。此方法用于 If-None-Match / ETag, 和 If-Modified-Since 和 Last-Modified 之间的缓存协商。 在设置一个或多个这些响应头后应该引用它。
    request.stale:与 request.fresh相反
    request.protocol:返回请求协议,“https” 或 “http”。当 app.proxy 是 true 时支持 X-Forwarded-Proto
    request.secure:通过 ctx.protocol == "https" 来检查请求是否通过 TLS 发出。
    request.ip:请求远程地址。 当 app.proxy 是 true 时支持 X-Forwarded-Proto。
    request.is(types...):检查传入请求是否包含 Content-Type 头字段, 并且包含任意的 mime type。 如果没有请求主体,返回 null,如果没有内容类型,或者匹配失败,则返回 false。 反之则返回匹配的 content-type。

    五、Response对象

    常用Response对象属性
    response.header:响应标头对象。
    response.socket:请求套接字。
    response.status:获取响应状态
    response.message:获取响应的状态消息.
    response.body:获取响应主体。
    response.get(field):不区分大小写获取响应标头字段值 field。
    response.set(field, value):设置响应标头 field 到 value
    response.redirect(url, [alt]):执行 [302] 重定向到 url.

    六、常用中间件

    koa中间件 Middleware
    koa-logger :开发样式记录器
    koa-basic-auth :用户身份认证
    koa-router:koa路由
    koa-body:解析http请求正文
    koa-compose :将多个中间件组合成一个
    koa-session:基于cookie的会话中间件,也支持外部会话存储、
    koa-csrf :防止跨域攻击的
    koa-views:使用任何模板引擎渲染视图
    koa-static:静态文件服务中间件
    查看更多 Middleware

    image.png
    image
    所有的请求经过一个中间件的时候都会执行两次,Koa 的模型可以非常方便的实现后置处理逻辑

    七、常见简单用法

    7.1网页模板

    const fs = require('fs');
    const Koa = require('koa');
    const app = new Koa();
    
    const main = ctx => {
        ctx.response.type = 'html';
        ctx.response.body = fs.createReadStream('./index.html');
    };
    
    app.use(main);
    app.listen(3000);
    

    7.2 原生路由

    const Koa = require('koa')
    const app = new Koa()
    app.use((ctx, next) => {
        //通过ctx.request.url获取用户请求路径
        if (ctx.request.url == '/') {
            ctx.body = '<h1>首页</h1>'
        } else if (ctx.request.url == '/about') {
            ctx.body = '<h1>关于</h1>'
        } else {
            ctx.body = '<h1>404 not found</h1>'
        }
    })
    app.listen(3000)
    

    7.3 koa-router 模块路由

    const Koa = require('koa')
    const Router = require('koa-router')
    
    const app = new Koa()
    const router = new Router()
    
    app.use(router.routes());
    //.get就是发送的get请求
    router.get('/',(ctx,next)=>{
      ctx.response.body = '<h1>首页</h1>'
    })
    router.get('/about',(ctx,next)=>{
      ctx.response.body = '<h1>关于</h1>'
    })
    
    app.listen(3000)
    

    7.4 静态资源

    const Koa = require('koa');
    const app = new Koa();
    const path = require('path');
    const serve = require('koa-static');
    
    const main = serve(path.join(__dirname));
    
    app.use(main);
    app.listen(3000);
    //   http://localhost:3000/index.html
    

    7.5 重定向跳转

    const Koa = require('koa');
    const Router = require('koa-router');
    const app = new Koa();
    const router = new Router()
    
    app.use(router.routes()).use(router.allowedMethods());
    
    router.get('/about',(ctx,next)=>{
      ctx.response.redirect('/');
    })
    router.get('/',(ctx,next)=>{
       ctx.body = '首页';
    })
    
    app.listen(3000);
    

    7.6 500错误

    const Koa = require('koa');
    const app = new Koa();
    
    const main = ctx => {
      ctx.throw(500);
    };
    
    app.use(main);
    app.listen(3000);
    

    7.6 404错误

    const Koa = require('koa');
    const app = new Koa();
    
    const main = ctx => {
      ctx.response.status = 404;
      ctx.response.body = 'Page Not Found';
      // 以上与ctx.throw(404)效果相同;
    };
    
    app.use(main);
    app.listen(3000);
    

    7.7 error事件监听

    const Koa = require('koa');
    const app = new Koa();
    
    const main = ctx => {
      ctx.throw(500);
    };
    app.on('error', (err, ctx) => {
      console.error('server error', err);//err是错误源头
    });
    
    app.use(main);
    app.listen(3000);
    

    7.8 try...catch处理error
    如果错误被try...catch捕获,就不会触发error事件。这时,必须调用ctx.app.emit(),手动释放error事件,才能让监听函数生效。

    const Koa = require('koa');
    const app = new Koa();
    
    const handler = async (ctx, next) => {
        try {
            await next();
        } catch (err) {
            ctx.response.status = err.statusCode || err.status || 500;
            ctx.response.type = 'html';
            ctx.response.body = '<p>您要看的页面出错咯</p>';
            ctx.app.emit('error', err, ctx);//释放error事件
        }
    };
    
    const main = ctx => {
        ctx.throw(500);
    };
    
    app.on('error', function (err) {
        //释放error事件后这里的监听函数才可生效
        console.log('错误', err.message);
        console.log(err);
    });
    
    app.use(handler);
    app.use(main);
    app.listen(3000);
    

    7.9 cookie

    const Koa = require('koa');
    const app = new Koa();
    
    const main = function(ctx) {
      const n = 'luckfine'
      ctx.cookies.set('user', n);
      ctx.response.body = 'user is :' + n;
      setTimeout(() => {
        console.log(ctx.cookies.get('user'))
      },5000)
    }
    
    app.use(main);
    app.listen(3000);
    

    7.10 上传

    const serve = require('koa-static');
    const koaBody = require('koa-body');
    const Koa = require('koa');
    const fs = require('fs');
    const app = new Koa();
    const os = require('os');
    const path = require('path');
    
    
    app.use(koaBody({ multipart: true }));
    
    // serve files from ./public
    app.use(serve(path.join(__dirname, '/public')));
    
    app.use(async function(ctx, next) {
      // ignore non-POSTs
      if ('POST' != ctx.method) return await next();
    
      const file = ctx.request.files.file;
      const reader = fs.createReadStream(file.path);
      const stream = fs.createWriteStream(path.join(os.tmpdir(), Math.random().toString()));
      reader.pipe(stream);
      console.log('uploading %s -> %s', file.name, stream.path);
    
      ctx.redirect('/');
    });
    
    app.listen(3000);
    

    相关文章

      网友评论

          本文标题:koa初见

          本文链接:https://www.haomeiwen.com/subject/xfdulctx.html