Node.js 封装仿照 express 的路由
2017-12-02 21:51
573 查看
我们想要仿照express来封装我们的路由,我们先来看看一个仿照express封装的一个简单路由demo,这有助于我们了解express,然后我们会一步步来实现我们自己的简单express路由。
主入口:
http-route.js
我们现在开始封装自己的express。
我们先来写一个例子:
利用上面,我们可以分别来封装我们的get和post方式。
当请求是get的时候,我们执行app.get(),当请求是post的时候,我们执行app.post()。
但是光区分get和post方式是不够的,我们还需要根据不同的请求的 URL 和其他需要的 GET 及 POST 参数,随后路由需要根据这些数据来执行相应的代码。 所以我们还需要注册路由,根据不同的URL来找到对应的路由。
我们先定义了一个对象G,跟之前一样我们还定义了app 方法,还有get方法。
我们先来看get方法
get方法的参数分别为,string是注册的路由名,比如’login’,当你请求/login的时候,他就会找到对应的login路由,callback是回调函数,就是具体路由内容。
我们再来看如何去注册一个路由。
我们调用了app.get方法。给它传了一个login的路由名,和一个回调函数。输出了一段文字。
上面这一段的效果相当于:
给G对象添加了一个login方法。就像我们之前写的路由一样:
我们再来看看app方法,这是路由的入口,也是程序的入口,根据不同的URL信息来找到对应的路由方法。
我们这里直接写死了请求login路由,实际上我们可以从request中获得url,得到我们要请求的路由,然后使用
最后我们只需要执行:
我们继续改造我们的express,我们要把他放到服务器上去,然后要根据我们访问url,去请求指定的路由。
我们来看app方法:
这次我们获取了请求request的url,然后解析获取了请求的pathname,根据pathname去找注册了的路由。
get方法还是和之前的类似:
然后我们注册了两个路由方法:
接下来就是创建一个Server:
上面的代码相当于:
好了,我们的目标基本实现了,现在我们需要再进一步封装我们的代码,把一些代码提出来封装成一个模块。
我们把它封装成为express-route.js
主程序:
好了我们自己的express也封装好了,通过上面的我们可以更加容易地理解express框架了。
主入口:
//index.js var route = require('./model/http-route.js'); var app = route(); var http = require('http'); var ejs=require('ejs'); var server = http.createServer(app); app.get('/', function (req, res) { res.send('首页'); }); app.get('/login', function (req, res) { res.send('login'); }); app.get('/register', function (req, res) { res.send('register'); }); app.get('/dologin', function (req, res) { ejs.renderFile('views/form.ejs',{},function(err,data){ res.end(data); }); }); app.post('/test', function (req, res) { console.log('POST', req.query); res.send(req.query); }); server.listen(8080, function () { console.log('listen ' + server.address().port); });
http-route.js
var url = require('url'); /** * 对resquest进行封装 * * @param {*} res */ var packingRes = function (res) { var end = res.end; res.end = function (data, encoding, callback) { if (data && !(data instanceof Buffer) && (typeof data !== 'function')) { if (typeof data === 'object') { data = JSON.stringify(data); } else if (typeof data === 'number') { data = data.toString(); } } end.call(res, data, encoding, callback); }; res.send = function (data, type) { res.writeHead(200, { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'text/' + (type || 'plain') + '; charset=UTF-8' } ); res.end(data); }; res.sendImg = function (data, type, timeout) { res.writeHead(200, { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'image/' + (type || 'png'), 'Content-Length': Buffer.byteLength(data), 'Cache-Control': 'max-age=' + (timeout || 5184000) } ); res.end(data); }; return res; }; /** * 路由规则 */ var route = function () { var self = this; this._get = {}; this._post = {}; /** * 处理请求 * * @param {*} req * @param {*} res */ var handle = function (req, res) { packingRes(res); var Url = url.parse(req.url, true); var pathname = Url.pathname; if (!pathname.endsWith('/')) { pathname = pathname + '/'; } var query = Url.query; var method = req.method.toLowerCase(); if (self['_' + method][pathname]) { if (method == 'post') { // 设置接收数据编码格式为 UTF-8 // req.setEncoding('utf-8'); var postData = ''; // 数据块接收中 req.on('data', function (postDataChunk) { postData += postDataChunk; }); // 数据接收完毕,执行回调函数 req.on('end', function () { try { postData = JSON.parse(postData); } catch (e) { } req.query = postData; self['_' + method][pathname](req, res); }); } else { req.query = query; self['_' + method][pathname](req, res); } } else { res.send(method + '请求路由地址不存在:' + pathname); } }; /** * 注册get请求 */ handle.get = function (string, callback) { if (!string.startsWith('/')) { string = '/' + string; } if (!string.endsWith('/')) { string = string + '/'; } self._get[string] = callback; }; /** * 注册post请求 */ handle.post = function (string, callback) { if (!string.startsWith('/')) { string = '/' + string; } if (!string.endsWith('/')) { string = string + '/'; } self._post[string] = callback; }; return handle; }; module.exports = function () { return new route(); };
我们现在开始封装自己的express。
我们先来写一个例子:
var app = function(){ console.log('app'); } app.get=function(){ console.log('app.get'); } app.post=function(){ console.log('app.post'); } app.post(); /*app.post*/ // app(); /*app*/ console.log(app);
利用上面,我们可以分别来封装我们的get和post方式。
当请求是get的时候,我们执行app.get(),当请求是post的时候,我们执行app.post()。
但是光区分get和post方式是不够的,我们还需要根据不同的请求的 URL 和其他需要的 GET 及 POST 参数,随后路由需要根据这些数据来执行相应的代码。 所以我们还需要注册路由,根据不同的URL来找到对应的路由。
var G={}; var app=function(req,res){ //console.log('app'+req); if(G['login']){ G['login'](req,res); /*执行注册的方法*/ } } //定义一个get方法 app.get=function(string,callback){ G[string]=callback; //注册方法 //G['login']=function(req,res){ // //} } //执行get方法 app.get('login',function(req,res){ console.log('login '+req); }) setTimeout(function(){ app('req','res'); },1000);
我们先定义了一个对象G,跟之前一样我们还定义了app 方法,还有get方法。
我们先来看get方法
//定义一个get方法 app.get=function(string,callback){ G[string]=callback; }
get方法的参数分别为,string是注册的路由名,比如’login’,当你请求/login的时候,他就会找到对应的login路由,callback是回调函数,就是具体路由内容。
我们再来看如何去注册一个路由。
app.get('login',function(req,res){ console.log('login '+req); })
我们调用了app.get方法。给它传了一个login的路由名,和一个回调函数。输出了一段文字。
上面这一段的效果相当于:
app.get=function(string,callback){ G[string]=callback; //注册方法 //G['login']=function(req,res){ // //} }
给G对象添加了一个login方法。就像我们之前写的路由一样:
module.exports = { login : function(req,res){ console.log('login '+req); }, }
我们再来看看app方法,这是路由的入口,也是程序的入口,根据不同的URL信息来找到对应的路由方法。
var app=function(req,res){ //console.log('app'+req); if(G['login']){ G['login'](req,res); /*执行注册的方法*/ } }
我们这里直接写死了请求login路由,实际上我们可以从request中获得url,得到我们要请求的路由,然后使用
if(G[routerName]){ G[routerName](req,res); /*执行注册的方法*/ }
最后我们只需要执行:
setTimeout(function(){ app('req','res'); },1000);
我们继续改造我们的express,我们要把他放到服务器上去,然后要根据我们访问url,去请求指定的路由。
var http=require('http'); var url=require('url'); var G={}; //定义方法开始结束 var app=function(req,res){ //console.log('app'+req); var pathname=url.parse(req.url).pathname; if(!pathname.endsWith('/')){ pathname=pathname+'/'; } if(G[pathname]){ G[pathname](req,res); /*执行注册的方法*/ }else{ res.end('no router'); } } //定义一个get方法 app.get=function(string,callback){ if(!string.endsWith('/')){ string=string+'/'; } if(!string.startsWith('/')){ string='/'+string; } // /login/ G[string]=callback; //注册方法 //G['login']=function(req,res){ // //} } //只有有请求 就会触发app这个方法 http.createServer(app).listen(3000); //注册login这个路由(方法) app.get('login',function(req,res){ console.log('login'); res.end('login'); }) app.get('register',function(req,res){ console.log('register'); res.end('register'); })
我们来看app方法:
//定义方法开始结束 var app=function(req,res){ //console.log('app'+req); var pathname=url.parse(req.url).pathname; if(!pathname.endsWith('/')){ pathname=pathname+'/'; } if(G[pathname]){ G[pathname](req,res); /*执行注册的方法*/ }else{ res.end('no router'); } }
这次我们获取了请求request的url,然后解析获取了请求的pathname,根据pathname去找注册了的路由。
get方法还是和之前的类似:
//定义一个get方法 app.get=function(string,callback){ if(!string.endsWith('/')){ string=string+'/'; } if(!string.startsWith('/')){ string='/'+string; } // /login/ G[string]=callback; //注册方法 //G['login']=function(req,res){ // //} }
然后我们注册了两个路由方法:
//注册login这个路由(方法) app.get('login',function(req,res){ console.log('login'); res.end('login'); }) app.get('register',function(req,res){ console.log('register'); res.end('register'); })
接下来就是创建一个Server:
//只有有请求 就会触发app这个方法 http.createServer(app).listen(3000);
上面的代码相当于:
http.createServer(function(req,res){ //console.log('app'+req); var pathname=url.parse(req.url).pathname; if(!pathname.endsWith('/')){ pathname=pathname+'/'; } if(G[pathname]){ G[pathname](req,res); /*执行注册的方法*/ }else{ res.end('no router'); } }).listen(3000);
好了,我们的目标基本实现了,现在我们需要再进一步封装我们的代码,把一些代码提出来封装成一个模块。
我们把它封装成为express-route.js
var url=require('url'); //封装方法改变res 绑定res.send() function changeRes(res){ res.send=function(data){ res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"}); res.end(data); } } //暴露的模块 var Server=function(){ var G=this; /*全局变量*/ //处理get和post请求 this._get={}; this._post={}; var app=function(req,res){ changeRes(res); //获取路由 var pathname=url.parse(req.url).pathname; if(!pathname.endsWith('/')){ pathname=pathname+'/'; } //获取请求的方式 get post var method=req.method.toLowerCase(); if(G['_'+method][pathname]){ if(method=='post'){ /*执行post请求*/ var postStr=''; req.on('data',function(chunk){ postStr+=chunk; }) req.on('end',function(err,chunk) { req.body=postStr; /*表示拿到post的值*/ //G._post['dologin'](req,res) G['_'+method][pathname](req,res); /*执行方法*/ }) }else{ /*执行get请求*/ G['_'+method][pathname](req,res); /*执行方法*/ } }else{ res.end('no router'); } } app.get=function(string,callback){ if(!string.endsWith('/')){ string=string+'/'; } if(!string.startsWith('/')){ string='/'+string; } // /login/ G._get[string]=callback; } app.post=function(string,callback){ if(!string.endsWith('/')){ string=string+'/'; } if(!string.startsWith('/')){ string='/'+string; } // /login/ G._post[string]=callback; //G._post['dologin']=function(req,res){ // //} } return app; } module.exports=Server();
主程序:
var http=require('http'); var ejs=require('ejs'); var app=require('./model/express-route.js'); console.log(app); http.createServer(app).listen(3000); app.get('/',function(req,res){ var msg='这是数据库的数据' ejs.renderFile('views/index.ejs',{msg:msg},function(err,data){ res.send(data); }) }) //登录页面 app.get('/login',function(req,res){ console.log('login'); ejs.renderFile('views/form.ejs',{},function(err,data){ res.send(data); }) }) //执行登录 app.post('/dologin',function(req,res){ console.log(req.body); /*获取post传过来的数据*/ res.send("<script>alert('登录成功');history.back();</script>") }) app.get('/register',function(req,res){ console.log('register'); res.send('register'); }) app.get('/news',function(req,res){ console.log('register'); res.send('新闻数据'); })
好了我们自己的express也封装好了,通过上面的我们可以更加容易地理解express框架了。
相关文章推荐
- node.js express 路由 select
- 对nodejs express 框架的简单封装实现快速开发
- nodejs express 路由
- Node.js Express 路由文件分类
- node.js express 支持中文路由的中间件
- Express---node.js-express框架中的主要方法,使用中间件关联 多个路由
- 夺命雷公狗---node.js---17之项目的构建在node+express+mongo的博客项目2之一,二级路由
- nodejs express 框架解密4-路由
- node.js 任务4 用express 自定义路由,接收增删改查请求
- Node.js的高性能封装 Express.js
- node.js+express+jade系列二:rotue路由的配置
- Express.js 3.0 发布,Node.js 的高性能封装
- express+nodeJS搭建服务、前后端交互、后端路由(一)
- node.js框架 服务器express的使用 及 route路由的使用
- Node.js开发入门(五)——Express里的路由和中间件
- 使用Node.js的express框架搭建一个简单项目并且添加了一个路由
- Node.js —— 使用express模块创建静态web服务器及其路由
- node.js零基础详细教程(5):express 、 路由
- Node.js开发入门—Express里的路由和中间件
- Node.js进行Web开发(一)--Express,路由控制,模板引擎