Node - 路由(四)

3,983 阅读4分钟

“Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine”官网的一句介绍大致是说“Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时”,简单来说就是一个能让JS运行在服务端的环境。

前言

又来了?嗯,又来了。 今天讲的主题是路由这块,Em...其实感觉这个主题也没什么可以讲的,调研了一下(其实就是百度、谷歌了一下),很少人讲Node中的路由。这是为什么呢?两个原因:第一,比较简单;第二,自己写太不方便、实用。所以,今天的内容很少,很少(水文?)。

什么是路由?

很多时候我们对接后端接口的时候,经常是不同功能对应不同的对接地址,那么后端如何实现不同的地址去实现相应功能的呢?如注册接口可能就是将用户信息插入数据库,登录接口就是验证一下数据库是否这个数据且是否正确这样子。而所划分的这些不同的地址我们可以称之为“路由”。

  • 注册:/api/register
  • 登录:/api/login
  • 查询列表:/api/list

(其实和前端路由也差不多是异曲同工之妙了,反正就是那样子,你懂的啦,不懂也不要问我,就这样子。)

直接开始

启动一个简单的服务,并打印一些东西。

const http = require('http');
const host = 'localhost';
const port = '8888';
const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  console.log(req.method); // --> POST
  console.log(req.url); // --> /api/register
  res.end('成功响应');
});
server.listen(port, host, () => {
  console.log(`Server running at http://${host}:${port}`);
});

我们直接访问http://localhost:8888/api/register 通过打印能知道req.method与req.url就是这次的猪脚了。

所以我们直接用if...else判断字符串我们就能直接区分不同路由了,做不同逻辑响应了。

const http = require('http');
const host = 'localhost';
const port = '8888';
const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  if(req.method === 'GET') {
    if(req.url === '/api/list') {
      res.end('查询列表接口响应');
    }else {
      res.end('GET请求响应');
    }
  }else if(req.method === 'POST') {
    if(req.url === '/api/register') {
      res.end('注册接口响应');
    }else if(req.url === '/api/login') {
      res.end('登录接口响应');
    }else {
      res.end('POST请求响应');
    }
  }
});
server.listen(port, host, () => {
  console.log(`Server running at http://${host}:${port}`);
});

修改完代码后重启服务,分别访问下上面三个路由,就能得到不同的响应结果了,大致这就是Node路由的原理过程了。(上面直接判断req.url来区分路由,如果是GET请求携带了参数就有点问题了,上面偷了一下懒,下面会有讲解,就看看有没有人踩这个坑了)

好了,就完结了,散了吧,散了吧。

就这?就这?

323.jpg

那必然是还没完呢(猛男低头),肯定得封装一下,让你舒服、用的爽一下。

搞一波

先上代码,再解释,新建router.js文件

const url = require('url');

function createApplication() {
  // 收集响应集合
  this.get = {};
  this.post = {};

  const APP = (req, res) => {
    // 借助url内置模块来获取路由
    let pathname = url.parse(req.url).pathname;
    // 统一转成小写处理
    let method = req.method.toLowerCase();

    // 处理一下传递参数
    if (this[method][pathname]){
      if (method ==='get'){
        // 将request与response对象传回对象的响应中
        this[method][pathname](req, res);
      }else {
        // 统一将post请求的参数放在req.body上
        let params = '';
        req.on('data', chunk => {
          params += chunk;
        });
        req.on('end', () => {
          req.body = params;
          this[method][pathname](req, res);
        })
      }
    }else {
      res.end('404');
    }
  };

  // APP身上挂载方法, 供导出后的对象使用
  APP.get = (url, cb) => {
    this.get[url] = cb;
  };
  APP.post = (url, cb) => {
    this.post[url] = cb;
  };

  return APP;
}

module.exports = createApplication();

主文件(app.js)

const http = require('http');
const host = 'localhost';
const port = '8888';
const app = require('./router'); // 引入router.js文件

const server = http.createServer(app);

app.post('/api/register', (req, res) => {
  res.write(`<head><meta charset="utf-8"/></head>`);
  res.end('注册接口响应')
});

app.post('/api/login', (req, res) => {
  res.write(`<head><meta charset="utf-8"/></head>`);
  res.end('登录接口响应')
});

app.get('/api/list', (req, res) => {
  res.write(`<head><meta charset="utf-8"/></head>`);
  res.end('查询列表接口响应')
});

server.listen(port, host, () => {
  console.log(`Server running at http://${host}:${port}`);
});

之后我们通过node app.js启动这个服务,再次访问上面三个路由,依次能得到不同的响应。

好了,成功了,这次真没有了。

微信图片_20201016183030.jpg

(呃......眼尖的同学应该发现了,这种方式和express框架的差不多,哈哈,不是巧合。所谓大树底下好乘凉,express与koa的源码都是非常优秀的东西,当自己没有思路抽象、封装一些东西的时候,这些源码就是最好的参考了,拜拜,牛逼吹完,撤退。)

个人感觉自己文笔不是很好,是个比较偏实践类的人,但偶尔也羡慕那些写文写得好的大佬,也想学学大佬们写些有趣的东西。所谓的菜鸟的自我修养,就是向大佬的看齐,即使当作学习的笔记也罢,反正就是把自己知道的东西说出来而已,这是我一个写文的念头。同时也我希望自己是个能以最简洁的言语讲清一个事要点的人,所谓读书在精不在多怎么一个方式和大家见面。