自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何用Node去寫一個(gè)Web應(yīng)用框架

開發(fā) 前端
大部分的node教程在這里會告訴你,我們很容易的建立的一個(gè)服務(wù)器。但是在實(shí)際使我們通常使用的是express.(f**k,難道Node必須要用express嗎?自己實(shí)現(xiàn)一個(gè)Web應(yīng)用框架真的很難嗎?)其實(shí)并不是。

第一步,用node輸出一個(gè)hello world

  1. var http=require('http'); 
  2. http.createServer(function(req,res){ 
  3.     var urlPares=url.parse(req.url); 
  4.     var query=querystring.parse(urlPares.query); 
  5.     res.end('hello world'); 
  6. }).listen(80); 

大部分的node教程在這里會告訴你,我們很容易的建立的一個(gè)服務(wù)器。但是在實(shí)際使我們通常使用的是express.(f**k,難道Node必須要用express嗎?自己實(shí)現(xiàn)一個(gè)Web應(yīng)用框架真的很難嗎?)其實(shí)并不是。

[[151676]]

那么既然打算自己寫我們首先要知道我們要做哪些事情。 1.路由或者智能路由 2.靜態(tài)文件輸出 3.session/cookie 4.模版渲染 5.數(shù)據(jù)庫處理 6.文件上傳

第二步,路由

路由好高大上的名字,它是干啥的?url對應(yīng)具體方法就是它該做的事情。 那么我們?yōu)槭裁床蛔寀rl對應(yīng)xxx文件的xx方法。 例如:/user/login能不能自動對應(yīng)到user.js的login方法上。實(shí)現(xiàn)起來很難么?其實(shí)只需要幾句代碼

  1. var fs = require("fs"); 
  2. module.exports=function(req,res){ 
  3.     var query=req.query; 
  4.     var urlPares=req.urlPares; 
  5.     var pathname=urlPares.pathname; 
  6.     var arr=pathname.split("/"); 
  7.     req.arr=arr; 
  8.     //start 這段代碼處理默認(rèn)行為??梢韵群雎?/span> 
  9.     if(arr.length==0||arr.length==1){ 
  10.         arr=["","index","index"]; 
  11.     }else if(arr.length==2){ 
  12.         arr.push("index"); 
  13.     } 
  14.     if(arr[1]==""){ 
  15.         arr[1]="index"
  16.     } 
  17.     if(arr[2]==""){ 
  18.         arr[2]="index"
  19.     } 
  20.     //end 這段代碼處理默認(rèn)行為??梢韵群雎?/span> 
  21.     if (fs.existsSync(APP_PATH+'/controller/'+arr[1]+'.js')){ 
  22.         var controller=require('./controller/'+arr[1]); 
  23.         if(controller[arr[2]]){ 
  24.             controller[arr[2]](req,res); 
  25.         }else
  26.             res.writeHead(404,{'Content-Type''text/plain' }); 
  27.             res.end("你訪問的控制器不存在指定方法"); 
  28.         } 
  29.     }else
  30.         res.writeHead(404,{'Content-Type''text/plain' }); 
  31.         res.end("你訪問的路徑不存在"); 
  32.     } 

通過fs判斷文件是否存在。然后去require它就行了。APP_PATH是個(gè)全局變量表示程序入口的路徑。

第三步,靜態(tài)文件輸出

靜態(tài)文件輸出我們需要一個(gè)庫MIME

  1. var url = require("url"); 
  2. var fs = require("fs"); 
  3. var mime = require('mime'); 
  4. /** 
  5.  * [[檢測是否為靜態(tài)資源]] 
  6.  * @param   {Object}   req [[Description]] 
  7.  * @param   {[[Type]]} res [[Description]] 
  8.  * @returns {bool} [[Description]] 
  9.  */ 
  10. module.exports = function (req, res) { 
  11.     //正則表達(dá)式檢測文件后綴 
  12.     var url_resource_reg = /.*\.(html|htm|gif|jpg|jpeg|bmp|webp|htc|swf|png|ico|txt|js|css)/; 
  13.     if (!url_resource_reg.test(req.url)) { 
  14.         return false
  15.     } 
  16.     var urlPares = url.parse(req.url); 
  17.     var pathname = urlPares.pathname; 
  18.     var fileUrl = APP_PATH + "/static" + pathname; 
  19.  
  20.     if (fs.existsSync(fileUrl)) { 
  21.         var contentType = mime.lookup(fileUrl); 
  22.         res.setHeader('Content-Type', contentType || "text/plain"); 
  23.  
  24.         var fileStream = fs.createReadStream(fileUrl); 
  25.         fileStream.pipe(res); 
  26.         fileStream.on('end', function () { 
  27.             res.end(); 
  28.         }); 
  29.         return true
  30.     } else { 
  31.         return false
  32.     } 

第四步,session/cookie

這里稍微有點(diǎn)。但是代碼量也不多

  1. var sessions = {}; 
  2. var sessionKey = 'session_key'
  3. var EXPIRES = 30 * 60 * 1000
  4. function randString(size) { 
  5.     var result = ''
  6.     var allChar = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  7.     size = size || 1
  8.     while (size--) { 
  9.         result += allChar.charAt(rand(0, allChar.length - 1)); 
  10.     } 
  11.     return result; 
  12. var generate = function () { 
  13.     var session = {}; 
  14.     session.id = Date.now() + randString(12); 
  15.     session.cookies = { 
  16.         expire: Date.now() + EXPIRES 
  17.     } 
  18.     sessions[session.id] = session; 
  19.     return session; 
  20. var parseCookie= function (cookie) { 
  21.     var cookies = {}; 
  22.     if (!cookie) { 
  23.         return cookies; 
  24.     } 
  25.     var list = cookie.split(";"); 
  26.     for (var i = 0; i < list.length; i++) { 
  27.         var pair = list[i].split("="); 
  28.         cookies[pair[0].trim()] = pair[1]; 
  29.     } 
  30.     return cookies; 
  31. var serializeCookies = function (cookies) { 
  32.     var arr = []; 
  33.     for (var key in cookies) { 
  34.         arr.push(serialize(key, cookies[key])); 
  35.     } 
  36.     return arr; 
  37. var serialize = function (name, value, option) { 
  38.     var pairs = [name + '=' + encodeURI(value)]; 
  39.     //設(shè)置cookie默認(rèn)共用"/"路徑 
  40.     option = option || { 
  41.         path: "/" 
  42.     }; 
  43.     if (option.maxAge) pairs.push('Max-Age=' + option.maxAge); 
  44.     if (option.domain) pairs.push('Domain=' + option.domain); 
  45.     if (option.path) pairs.push('Path=' + option.path); 
  46.     if (option.expires) pairs.push('Expires=' + option.expires); 
  47.     if (option.httpOnly) pairs.push('HttpOnly'); 
  48.     if (option.secure) pairs.push('Secure'); 
  49.     return pairs.join('; '); 
  50. module.exports = function (req, res) { 
  51.     req.cookies = parseCookie(req.headers.cookie); 
  52.     var id = req.cookies[sessionKey]; 
  53.     if (!id) { 
  54.         req.session = generate(); 
  55.     } else { 
  56.         var session = sessions[id]; 
  57.         if (session) { 
  58.             if (session.cookies.expire > Date.now()) { 
  59.                 session.cookies.expire = Date.now() + EXPIRES; 
  60.                 req.session = session; 
  61.             } else { 
  62.                 delete sessions[id]; 
  63.                 req.session = generate(); 
  64.             } 
  65.         } else { 
  66.             req.session = generate(); 
  67.         } 
  68.     } 
  69.     for (var key in sessions) { 
  70.         if (sessions[key].cookies.expire < Date.now()) { 
  71.             delete sessions[key]; 
  72.         } 
  73.     } 
  74.     var writeHead = res.writeHead; 
  75.     res.writeHead = function () { 
  76.         delete req.cookies[ham_sessionKey]; 
  77.         var sessionStr = serialize(ham_sessionKey, req.session.id); 
  78.         res.setHeader('Set-Cookie', serializeCookies(req.cookies).concat(sessionStr)); 
  79.         return writeHead.apply(res, arguments); 
  80.     } 

第五步,模版渲染

這是最簡單的。因?yàn)槲矣?a >https://github.com/aui/artTemplate ,自己用自己喜歡的模塊組件就行了

第六步,數(shù)據(jù)庫處理

這里可以是用一些ORM框架。例如https://github.com/dresende/node-sql-query

第七步,文件上傳,post

這里只需要一個(gè)組件https://github.com/felixge/node-formidable

第八步,就是你把上面的代碼組織起來。

可以參考我的實(shí)現(xiàn) https://coding.net/u/as3long/p/today/git/tree/master/node_modules/ham 代碼比較亂,見諒。

責(zé)任編輯:王雪燕 來源: IMWeb Team
相關(guān)推薦

2017-06-08 15:53:38

PythonWeb框架

2021-06-25 10:45:43

Netty 分布式框架 IO 框架

2021-06-24 10:27:48

分布式架構(gòu)系統(tǒng)

2022-03-17 15:34:47

printf日志

2020-10-29 16:00:03

Node.jsweb前端

2023-02-26 01:37:57

goORM代碼

2020-08-07 10:40:56

Node.jsexpress前端

2014-11-25 14:04:59

DockerDocker Nodeweb應(yīng)用部署

2023-09-21 08:00:00

ChatGPT編程工具

2009-05-08 09:32:27

JavaWeb編程框架

2019-08-12 10:45:54

Flutter框架Native

2023-05-10 08:05:41

GoWeb應(yīng)用

2017-12-12 15:24:32

Web Server單線程實(shí)現(xiàn)

2016-09-06 19:45:18

javascriptVue前端

2018-03-23 10:00:34

PythonTensorFlow神經(jīng)網(wǎng)絡(luò)

2015-04-29 10:02:45

框架如何寫框架框架步驟

2012-01-04 13:55:23

Canvas

2024-03-27 11:18:02

2017-03-20 17:59:19

JavaScript模板引擎

2017-03-15 08:43:29

JavaScript模板引擎
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號