koa2入门系列(五)

模拟接口请求,以及数据处理中间件

突然踏入node相关的学习,你或许曾经会有这样的疑问:前端既然已经有了React、Vue、Angular2三条大船,为何还要有expresskoa等一系列的node框架呢?
作为前端工作人员而言,因为前面三条大船都是处理前端业务的,而鉴于我大JS的强大,前端人员想要把魔抓伸向后台,想要把一切都掌握在手里,从此踏上人生颠覆...这就要用到node的后端能力了。

对前端而言,后端提供的能力,自然就是数据请求。而其实对于浏览器而言,一切都是请求。所以,下面就开始讨论koa对接口请求的处理:

1、get请求处理

上一节处理了静态文件,对于浏览器而言,读取静态文件,其实就是相当于get请求。
下面改造一下配置文件

const koa = require('koa');
const Router = require('koa-router');

const app = new koa();
const router = new Router();

const hostName = '192.168.3.27';
const port = 3000;

// 配置路由
router.get('/', async ctx => {
  // ctx  上下文 context ,包含了request 和response等信息
  // 返回数据    相当于:原生里面的res.writeHead()  res.end()
  console.log(ctx);
  ctx.body = '首页';
});
router.get('/news/:id', async ctx => {
  /**
     在 koa2 中 GET 传值通过 request 接收,但是接收的方法有两种:query 和 querystring。
     query:返回的是格式化好的参数对象。
     querystring:返回的是请求字符串。
  */
  //从ctx中读取get传值
  console.log(ctx.url); // /news/123
  console.log(ctx.params); // { id: '123' }
  ctx.body = '新闻页';
});

// 匹配任何路由,如果不写next,这个路由被匹配到了就不会继续向下匹配
app.use(async (ctx, next) => {
  console.log('中间件');
  await next();

  if (ctx.status === 404) {
    ctx.status = 404;
    ctx.body = '404 页面';
  }
});

app.use(router.routes());
app.use(router.allowedMethods());
/**
  router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
  看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
  路由中间件最后调用.此时根据 ctx.status 设置 response 响应头
  可以配置也可以不配置,建议配置,
*/

app.listen(port, hostName);

重启服务,然后刷新页面,处理页面展示首页字样,在命令终端可以看到下面输入

chenhy-2:koalern chenhaoyin$ node app.js
中间件
{
  request: {
    method: 'GET',
    url: '/',
    header: {
      host: '192.168.3.27:3000',
      connection: 'keep-alive',
      'cache-control': 'max-age=0',
      'upgrade-insecure-requests': '1',
      'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
      accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
      'accept-encoding': 'gzip, deflate',
      'accept-language': 'zh-CN,zh;q=0.9'
    }
  },
  response: {
    status: 404,
    message: 'Not Found',
    header: [Object: null prototype] {}
  },
  app: { subdomainOffset: 2, proxy: false, env: 'development' },
  originalUrl: '/',
  req: '<original node req>',
  res: '<original node res>',
  socket: '<original node socket>'
}

从命令行的输出看,可知浏览器在进入根目录的时候,进行的是get请求。然后我们再在浏览器后面输入/news/123,然后刷新页面,可以看到除了页面展示新闻页字样,命令行下面会展示

中间件
/news/123
{ id: '123' }
中间件
/news/123
{ id: '123' }

到这里你会发现,这跟我们平时写前端业务逻辑时的get请求的情况是一样的。
接下来,我们模拟post请求。

2、post请求处理

利用表单,可以发出post请求

  • 下面改造一下index.ejs文件
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title></title>
  </head>
  <body>
    <form action="/add" method="post">
      用户名: <input type="text" name="username" />
      <br />
      <br />
      密 码: <input type="password" name="password" />
      <br />
      <br />
      <button type="submit">提交</button>
    </form>
  </body>
</html>
  • 接着是配置文件读取index.ejs文件
//引入 koa模块
const Koa = require('koa');
const Router = require('koa-router'); // 用于接口请求(模版文件的加载其实就是get请求)
const views = require('koa-views'); // 用于加载模版文件
//实例化
const app = new Koa();
const router = new Router();

//配置模板引擎中间件
app.use(
  views('views', {
    extension: 'ejs'
  })
);

router.get('/', async ctx => {
  await ctx.render('index', {});
});

router.post('/add', async ctx => {
  // 不用bodypaser中间件的时候需要自己处理数据
  getData = function() {
    return new Promise(function(resolve, reject) {
      try {
        let str = '';
        ctx.req.on('data', function(chunk) {
          str += chunk;
        });
        ctx.req.on('end', function(chunk) {
          resolve(str);
        });
      } catch (err) {
        reject(err);
      }
    });
  };
  let data = await getData();
  ctx.body = data;
});

//启动路由
app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000);
  • 重启服务,刷新浏览器,页面会出现一个表单
  • 然后输入用户名和密码,点击提交,触发表单的action动作,并发起post请求。这里要注意的是action="/add"中的/add必须有对应的路由配置才能匹配跳转,否则就会提示Not Found或者进入对应的404页面

    到了这里,就基本上完成了对post请求的处理。
    然而,回到我们日常开发工作中,接口返回字符串文本信息,然后自己再去解析,那是n多年前甚至是jquery以前的时代的处理方式,都到了0202年了,这种数据的返回方式叔叔能忍,婶婶不能忍啊!所以,就有了下面的koa-bodyparser的使用。

3、响应数据的处理

  • 下载中间件yarn add koa-bodyparser
  • 在配置文件中引入并做相应的获取处理
//引入 koa模块
const Koa = require('koa');
const Router = require('koa-router'); // 用于接口请求(模版文件的加载其实就是get请求)
const views = require('koa-views'); // 用于加载模版文件
const bodyParser = require('koa-bodyparser'); // 用于将请求返回的数据自动转成json数据

//实例化
const app = new Koa();
const router = new Router();

//配置模板引擎中间件
app.use(
  views('views', {
    extension: 'ejs'
  })
);

//配置 koa-bodyparser 中间件
app.use(bodyParser());

router.get('/', async ctx => {
  await ctx.render('index', {});
});

router.post('/add', async ctx => {
  let data = ctx.request.body;
  ctx.body = data;
});

//启动路由
app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000);

重启服务,刷新浏览器后输入用户名和密码,点击提交,出现下面画面


OK,得到想要的json格式的数据,省去了一堆的数据处理方式,并最终完成对post请求的模拟,简单快捷,完美!。

ps

本文只是为了引出koa-bodyparser中间件的使用而做的简单get和post的请求模拟,想要模拟如deleteput等方式以及别的尝试的,请自行摸索。

当然,如果有更全更好的方式,希望可以给鄙人丢个链接学习学习,小弟感激不尽。
本文只作抛砖引玉之用。

终章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容