2021-06-04 node.js 封装一个简易的express

前言

此篇内容记录本人编程过程中所遇到的一些问题和解决的办法。仅供参考,有些内容引用别处。[非商用,如侵删]

正文

搭建基本结构

先来看看基本的express用法

const express = require('express');
const app = express();
//端口号
let prot = 3505;
//路由
app.get('/news'(req,res)=>{
	console.log('收到GET请求')
}}
app.post('/login'(req,res)=>{
	console.log('收到POST请求')
}}
//启动服务
app.listen(port,()=>{
	console.log(`localhost${port} Server start success...`)
})

首先 这里的app是调用了express这个函数,让我们可以操作 app. 来调用其中的方法
了解了这一点 我们先搭一个最基本的结构

//epxress.js
//外层包裹一个对象把app return出去
let express = () => {
	//主体或入口 所有的方法都是基于这个函数 接收传递进来的req
	let app = (req,res) => {
		
	}
	app.get = ()=>{
	console.log('我是app的get方法')
	}
	app.post = ()=>{}
	app.listen= ()=>{}
	//....
	return app
}
module.exports = express

现在我们为app创建了自己的方法,打印出来可以看一下,确实有这些方法我们可以试着调用一下
在这里插入图片描述

接下来我们可以在这个基础结构上做文章 首先实现app.listen()

app.listen()

//express.js
const http = require('http')        <-*新增
let express = () => {
	//主体或入口 所有的方法都是基于这个函数 接收传递进来的req
	let app = (req,res) => {
		
	}
	
	app.get = function () {
	    console.log('我是app的get方法');
	}
	
	app.post = function () {}
	
    app.listen = function () {
	    let server = http.createServer(app)
	    server.listen(...arguments) 
	   //因为不确定传入几个参数这里用了 扩展运算符 ... 和 arguments 
	}
	//....
	return app
}
module.exports = express

app.js里面引用一下

//app.js
const epxress = ('./express')

const app = express()

app.listen(3505,()=>{
console.log('localhost:3501 Server start success!')
})

在这里插入图片描述

构建app.method()方法

这里我们需要了解一下 express 是怎么设计的 先看看网上的截图
在这里插入图片描述

这里我们可以把app.get('/login',callback))想象成是向一个全局Routes数组里面push一个个的对象比如

app.get('/login',function(){
	console.log('我是向/login发起get请求的回调函数')
})
app.post('/news',function(){
	console.log('我是向/news发起post请求的回调函数')
})

Routes里面的结构应该是这样的

Routes = [
{method:'get',path:'/login',callbock:[Function]}
{method:'post',path:'/news',callbock:[Function]}
]

一层一层的 layer

//express.js
const http = require('http')        <-*新增
let express = () => { 
	//主体或入口 所有的方法都是基于这个函数 接收传递进来的req
	let app = (req,res) => {
		
	}
	
    app.Routes = [] //保管注册的路由
    app.get = function(path,callback){
		let layer = {
			method:'get',
			path,
			callback
		}
		app.Routes.push(layer)
    console.log('get注册成功');
    console.log('Rotes内容:',app.Routes);
	}		
	app.post= function(path,callback){
		let layer = {
			method:'post',
			path,
			callback
		}
		app.Routes.push(layer)
    console.log('post注册成功');
    console.log('Rotes内容:',app.Routes);
	}
	
    app.listen = function () {
	    let server = http.createServer(app)
	    server.listen(...arguments) 
	   //因为不确定传入几个参数这里用了 扩展运算符 ... 和 arguments 
	}
	//....
	return app
}
module.exports = express

可以看到 我们这里打印的 Routes里面的结构与上面一致
在这里插入图片描述

但是 请求的种类有很多 我们需要不同的请求类型来区分 前端 是发起删除请求还是添加的请求
所以我们不能只设置POSTGET 接下来我们把注册这一步再改进一下

function createRoutesMethds(method) {
    return function (path, callback) {
		let layer = {
	        method,
	        path, // 不包含查询字符串
	        callback
	    };
	    // 把这一层放入存储所有路由层信息的数组中
	    app.Routes.push(layer);
	}
}
let m = http.METHODS.map((m) => { return m.toLowerCase() });
m.forEach(method => {
	app[method] = createRoutesMethds(method)
})

通过forEach遍历 保管所有请求类型的数组m 为app创建方法以请求类型method命名
每次调用method方法 都会调用创建的函数createRoutesMethods()向数组Routes中Push一个对象
在这里插入图片描述

解析Request

获取path/method/query

例如:
当用户在浏览器发起一个http://localhost:3505/news 请求
那么app这个函数会接收到request,response这两个请求参数 我们需要解析requset 拿到 请求的路径path和方法method还需要携带的参数 querybody
在这里插入图片描述

上代码

const querystring = require('querystring')
function requestData(req,res){
  req.path = req.url.split('?')[0]
  req.query = querystring.parse(req.url.split('?')[1])
  req.method = req.method.toLowerCase()
  console.log({
    reqPath:req.path,
    reqQuery:req.query,
    reqMethod:req.method
  });
}
module.exports = requestData

req.path存放用户请求的路径, 通过字符串.split解析以?分隔 取下标0 可以拿到’/login’
req.query存放用户发起get请求时携带的参数 通过字符串.split解析以?分隔 取下标1 然后通过querystring的方法 转化为对象
req.method存放用户的请求方式 默认为大写 但是我们后续匹配路由的内容都为小写 所以转化后传回去
请求http://localhost:3505/login?code=5&name=8
打印如下
在这里插入图片描述

接下来需要拿用户通过表单提交数据的Post请求 会相比较复杂一些

####获取PostData
在node.js中 获取post的请求参数的方法只有通过监听data事件的方式获取 并且我们需要以流的方式记录 所以这里需要用到Promise来处理 看代码

function requestData(req,res){
  
.....
  return New Promise((resolve,reject)=>{
  //做判断 如果请求方式 method 不是 post的话 直接 resolve({}) 返回一个空
	  if(req.method !== 'post'){
		  resolve({})
	  }else{
		  //创建一个空字符串 接收chunk
		  let postData = '';
		  //监听 data 事件 有数据进来 就用chunk 写入postData 
		  req.on('data',chunk>{
			postData += chunk 
		  })
		  //监听data结束事件 结束时 resolve(pastData)  注意!需要把他转化为一个对象
	      req.on('end',()=>{
			  resolve(querystring.parse(decodeURIComponent(postData)));
		  })
	  }
  })
}
module.exports = requestData

接下来需要在
app.js中引入这个方法

const requestData = require('./requestData')
 let app = (req, res) => {
    requestData(req,res).then((result)=>{
      req.body = result
      //打印看一下结果
      console.log({
        reqPath:req.path,
        reqQuery:req.query,
        reqMethod:req.method,
        reqBody:req.body
      });
    })
  }

来看一下结果
四个参数我们都拿到了
在这里插入图片描述

调用app.method()方法

app.send()

app.use()

.
.

未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比苦瓜苦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值