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里面的结构与上面一致
但是 请求的种类有很多 我们需要不同的请求类型来区分 前端 是发起删除
请求还是添加
的请求
所以我们不能只设置POST
和GET
接下来我们把注册这一步再改进一下
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
还需要携带的参数 query
和body
上代码
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()
.
.
未完待续…