专栏首页前端技术分享Koa - 初体验(写个接口)

Koa - 初体验(写个接口)

前言

不会node.js的前端不是一个好前端!

  这几年node.js确实是越来越火了,好多公司对node.js都开始有要求。虽说前端不一定要会后端,但想要成为一个优秀的前端,node.js是必经之路。

  我对于node.js的第一印象,认为它是一门后端语言,只是前端学习起来成本会更低更好上手。慢慢经过了解后,使用node.js写接口对于前端来说很方便,但不仅限于写接口。在一些大公司里,node.js并不是开发接口的首选目标,而是作为中间层来使用。我们都知道分工合作,让专业的人做更专业的事,工作效率会大大提高。node.js作为中间层的存在,可以让后端更专注于写接口和管理数据。

  试想一下,现在由于业务逻辑改变,后端需要对数据接口进行更改,是否会花费时间?如果你会node.js,那么你就可以通过node.js来做数据聚合,从几个接口中拼接数据供前端使用,而不需要为数据结构和数据内容烦恼,并且你不用担心效率,因为node.js天生异步。

包括我们常用的一些脚手架工具也是基于node.js环境搭建,你甚至还可以使用node.js来做数据挖掘,也就是我们所说的爬虫,node.js的应用层面还有很多。以上都是我了解到的一些信息。

  目前node.js比较主流框架分为express、koa、egg。koa作为新一代的框架,由开发express的原班人马打造,支持ES7 async/await,抛弃回调函数,在写法上更自然。koa没有绑定任何中间件,关键的设计点是在其低级中间件层中提供高级“语法糖”,koa的体积也因此更小。(中间件在koa中是一个很重要的存在,在后面我会着重去学习它)

  接下来,我要开始koa入坑之路。

koa初体验

hello,koa!

安装koa ,npm i koa

创建一个app.js,命令行执行 node app

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

app.context.msg = 'Hello Koa!' 
app.use(async ctx => {
  ctx.body = ctx.msg;
});

app.listen( 3000);

app.context 为执行上下文添加属性和方法  

app.use 将给定的中间件方法添加到应用程序中

该方法接收ctxnext作为参数,ctx 是执行上下文,里面存储了request和response等信息,还有ctx.body,我们可以通过它来返回数据,next作为函数调用,将执行权交给下一个中间件执行。

这里我先安装个nodemon,因为每次更改文件时,都需要重新执行命令以更新代码,这种重复性的工作就交给模块来处理。

通过 npm i nodemon 安装好后,命令行执行 nodemon app,这样每次更改文件时,nodemon都自动刷新。

Koa-router 路由管理

为了代码的可维护性,减少代码量。使用路由管理显得尤为重要,koa框架也有自己对应的路由管理模块(koa-router),我们可以通过npm 下载使用。

var Koa = require('koa' );
var Router = require('koa-router' );
 
var app = new Koa();
var router = new Router();
 
router.get( '/', (ctx, next) => {
      ctx.body = 'hello'
});

//使用路由中间件
app
  .use(router.routes())
  .use(router.allowedMethods());

app.listen( 3000 )
     

routes 注册使用路由

allowedMethods 处理的业务是当所有路由中间件执行完成之后,若 ctx.status 为空或者404的时候,丰富 response 对象的 header 头,不加问题也不大,官方例子有加上,所以我这里也加了

这时访问3000端口就可以得到ctx.body 返回的内容

get请求

1. 获取接口query参数

通过查询 ctx.request.query 得到get参数, ctx.request.header 得到请求时的头部信息,ctx.request.method 得到请求方法。这样可以对应的来做一些判断,例如请求的参数是否合法,请求方法是否合法。

router.get( '/get', (ctx, next) => {
      let id = ctx.request.query.id
      ctx.body = {
           id,
           code: 1
      }
});

2. 命名路由 获取参数

router.get( '/get/:id', (ctx, next) => {
      let id = ctx.request.params.id
      ctx.body = {
           id,
           code: 1
      }
});

例如请求地址为 /get/123,通过 ctx.request.params 获取参数

这写法让我想起了vue-router,设置params可以说是一样了。

post请求

原生获取post请求的参数,需要监听ctx.req的data事件和end事件,分段拼接成完整的字符串,然后还需要切割转码。所以在获取post参数时,我会借助 koa-bodyparser 来减少不必要的操作。

在引入 koa-bodyparser 时,需要注意的是顺序问题,使用 koa-bodyparser 需要放在使用路由之前,这是由于中间件执行顺序的原因(暂且理解为 bodyparser 经过处理,把处理好的值转交到路由)

var bodyParser = require('koa-bodyparser');

app.use(bodyParser());

app
    .use(passport.initialize())
    .use(passport.session())

借助中间件koa-bodyparser,访问 ctx.request.body 得到post参数

通过 ctx.set 设置返回头,设置多个时可传入对象

router.post('/post', ctx=>{
   //设置允许跨域
   ctx.set('Access-Control-Allow-Origin','*')
    ctx.body = {
        code:1,
        postParams:ctx.request.body
    }
})

路由模块化管理

试想一下,现在文件中写有多个接口,我们在开发和调试起来都会特别麻烦,浪费时间。为了更好的管理接口,现在需要把接口按照功能抽离出来,封装到一个个的JS文件中,并存放到routes文件夹下。

例如,创建 user.js 来存放用户相关的接口

const Router = require('koa-router')
const route = new Router()
const jwt = require('jsonwebtoken')

route.get('/getToken', async (ctx)=>{
    let {name,id} = ctx.query
    if(!name && !id){
        ctx.body = {
            msg:'不合法',
            code:0
        }
        return
    }
    //生成token
    let token = jwt.sign({name,id},'secret',{ expiresIn: '1h' })
    ctx.body = {
        token: token,
        code:1
    }
})

route.get('/getUser', async ctx=>{
    let id = ctx.query.id
    ctx.body = {
        user:ctx.payload,
        id,
        code:1
    }
})

route.get('/getAllUser', async ctx=>{
    let type = ctx.query.type
    if(type){
        ctx.body = {
            type,
            code:1
        }
    }else{
        ctx.body = {
            msg:'缺少参数type',
            code:0
        }
    }
})

module.exports = route

以上代码,将写好的接口暴露出去,供app.js注册使用

app.js代码(部分代码省略)

let urls = fs.readdirSync(__dirname + '/routes')
urls.forEach((element) => {
    //routes里的js接口文件
    let module = require(__dirname + '/routes/' + element)
    //routes里的文件名作为 路由名
    router.use('/' + element.replace('.js', ''), module.routes())
})

//使用路由
app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

以上代码,我大概讲下流程

1. fs文件模块读取routes文件夹目录内容(获得的是一个文件名的数组) 2. 数组遍历,引入接口文件,将文件名作为路由名,注册使用路由

将 user.js 作为例子,user.js 内有一个 getUser 的接口,我访问的api地址为 /user/getUser

头部信息处理

在前后端交互中,头部信息也是很关键的一步,通过对头部信息的配置,可以对请求作出一些限制,或者是一些优化。

这里我会使用 koa2-cors 为例子,来对跨域做cors处理(部分代码省略)。

const cors = require('koa2-cors')

app.use(cors({
    origin: function(ctx) {
      return 'http://127.0.0.1:5500';//cors
    },
    exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
    maxAge: 5,
    credentials: true,
    allowMethods: ['GET', 'POST'],
    allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}))

app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

origin : 接受字符串和函数,这里配置的就是允许跨域的域名,如果允许所有域名跨域可传入 * allowMethods : 允许请求的方式 allowHeaders : 允许接受的头部信息

其他的配置选项可以在npm上查看:https://www.npmjs.com/package/koa2-cors

写在最后

本文通过路由中间件简单实现接口,模块化管理接口文件,还对接口进行跨域处理。

主要还是玩模块,通过模块可以组合出适合自己业务的系统。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Koa源码解析,带你实现一个迷你版的Koa

    本文是我在阅读 Koa 源码后,并实现迷你版 Koa 的过程。如果你使用过 Koa 但不知道内部的原理,我想这篇文章应该能够帮助到你,实现一个迷你版的 Koa ...

    WahFung
  • require.context批量引入文件

    require.context 是由webpack内部实现,require.context在构建时,webpack 在代码中进行解析。

    WahFung
  • Koa - 使用koa-multer上传文件(上传限制、错误处理)

    上传文件在开发中是很常见的操作,今天我选择使用koa-multer中间件来实现这一功能,除了上传文件外,我还会对文件上传进行限制,以及发生上传错误时的处理。

    WahFung
  • 【从前端到全栈】- koa快速入门指南

    随着技术的不断发展,前端工程师也被赋予了越来越多的职责。不再是从前只需要切个图,加个css样式就能完成任务的切图仔了。接下来这篇文章,完成一个简单的登录注册,能...

    用户2356368
  • canvas绘制图形时beginPath应用

    当我们在使用canvas绘制图形的时候,不免都会使用到beginPath这个方法。今天我们就来讲解一下这个函数的重要性以及应用。

    小明爱学习
  • Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    前言   前面一有写到一篇Node.js+Express构建网站简单示例https://cloud.tencent.com/developer/article/...

    Porschev
  • python中回顾布尔类型,为条件语句预热

    判断结果在计算机中用布尔类型来表示,判断后,返回的结果,就是True或者False

    刘金玉编程
  • curl和https,及openssl

    如果使用curl访问https(注意不是http),则会牵涉到OpenSSL,就需要注意多线程安全问题。 一是OpenSSL需要编译成多线程安全版本,二是...

    一见
  • 前端标注切图利器-像素大厨(PxCook) 原

    之前一直用ps自带的智能切图,由于ps智能切图不能切固定大小的图,在网上找到了一个比较好的前端神器像素大厨 PxCook,不光能切图而且也能标注,方便快捷,易于...

    tianyawhl
  • 急 | Linux再曝安全漏洞Bash 比心血还严重

    Linux再曝安全漏洞Bash 比心血还严重 安全更新: 今天刚刚爆出Bash安全漏洞,SSH bash紧急安全补丁!重要!测试是否存在漏洞,执行以下命令:...

    小小科

扫码关注云+社区

领取腾讯云代金券