如何用Node去写一个Web应用框架

 我来答
匿名用户
2016-12-16
展开全部

第一步,用node输出一个hello world

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


大部分的node教程在这里会告诉你,我们很容易的建立的一个服务器。但是在实际使我们通常使用的是express.(f**k,难道Node必须要用express吗?自己实现一个Web应用框架真的很难吗?)其实并不是。
那么既然打算自己写我们首先要知道我们要做哪些事情。 1.路由或者智能路由 2.静态文件输出 3.session/cookie 4.模版渲染 5.数据库处理 6.文件上传
第二步,路由
路由好高大上的名字,它是干啥的?url对应具体方法就是它该做的事情。 那么我们为什么不让url对应xxx文件的xx方法。 例如:/user/login能不能自动对应到user.js的login方法上。实现起来很难么?其实只需要几句代码
   

 var fs = require("fs"); 
    module.exports=function(req,res){ 
        var query=req.query; 
        var urlPares=req.urlPares; 
        var pathname=urlPares.pathname; 
        var arr=pathname.split("/"); 
        req.arr=arr; 
        //start 这段代码处理默认行为。可以先忽略 
        if(arr.length==0||arr.length==1){ 
            arr=["","index","index"]; 
        }else if(arr.length==2){ 
            arr.push("index"); 
        } 
        if(arr[1]==""){ 
            arr[1]="index"; 
        } 
        if(arr[2]==""){ 
            arr[2]="index"; 
        } 
        //end 这段代码处理默认行为。可以先忽略 
        if (fs.existsSync(APP_PATH+'/controller/'+arr[1]+'.js')){ 
            var controller=require('./controller/'+arr[1]); 
            if(controller[arr[2]]){ 
                controller[arr[2]](req,res); 
            }else{ 
                res.writeHead(404,{'Content-Type': 'text/plain' }); 
                res.end("你访问的控制器不存在指定方法"); 
            } 
        }else{ 
            res.writeHead(404,{'Content-Type': 'text/plain' }); 
            res.end("你访问的路径不存在"); 
        } 
    }


通过fs判断文件是否存在。然后去require它就行了。APP_PATH是个全局变量表示程序入口的路径。
第三步,静态文件输出
静态文件输出我们需要一个库MIME
  

  var url = require("url"); 
    var fs = require("fs"); 
    var mime = require('mime'); 
    /** 
     * [[检测是否为静态资源]] 
     * @param   {Object}   req [[Description]] 
     * @param   {[[Type]]} res [[Description]] 
     * @returns {bool} [[Description]] 
     */ 
    module.exports = function (req, res) { 
        //正则表达式检测文件后缀 
        var url_resource_reg = /.*\.(html|htm|gif|jpg|jpeg|bmp|webp|htc|swf|png|ico|txt|js|css)/; 
        if (!url_resource_reg.test(req.url)) { 
            return false; 
        } 
        var urlPares = url.parse(req.url); 
        var pathname = urlPares.pathname; 
        var fileUrl = APP_PATH + "/static" + pathname; 
        if (fs.existsSync(fileUrl)) { 
            var contentType = mime.lookup(fileUrl); 
            res.setHeader('Content-Type', contentType || "text/plain"); 
            var fileStream = fs.createReadStream(fileUrl); 
            fileStream.pipe(res); 
            fileStream.on('end', function () { 
                res.end(); 
            }); 
            return true; 
        } else { 
            return false; 
        } 
    } 
第四步,session/cookie
这里稍微有点。但是代码量也不多
    var sessions = {}; 
    var sessionKey = 'session_key'; 
    var EXPIRES = 30 * 60 * 1000; 
    function randString(size) { 
        var result = ''; 
        var allChar = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
        size = size || 1; 
        while (size--) { 
            result += allChar.charAt(rand(0, allChar.length - 1)); 
        } 
        return result; 
    } 
    var generate = function () { 
        var session = {}; 
        session.id = Date.now() + randString(12); 
        session.cookies = { 
            expire: Date.now() + EXPIRES 
        } 
        sessions[session.id] = session; 
        return session; 
    } 
    var parseCookie= function (cookie) { 
        var cookies = {}; 
        if (!cookie) { 
            return cookies; 
        } 
        var list = cookie.split(";"); 
        for (var i = 0; i < list.length; i++) { 
            var pair = list[i].split("="); 
            cookies[pair[0].trim()] = pair[1]; 
        } 
        return cookies; 
    } 
    var serializeCookies = function (cookies) { 
        var arr = []; 
        for (var key in cookies) { 
            arr.push(serialize(key, cookies[key])); 
        } 
        return arr; 
    } 
    var serialize = function (name, value, option) { 
        var pairs = [name + '=' + encodeURI(value)]; 
        //设置cookie默认共用"/"路径 
        option = option || { 
            path: "/" 
        }; 
        if (option.maxAge) pairs.push('Max-Age=' + option.maxAge); 
        if (option.domain) pairs.push('Domain=' + option.domain); 
        if (option.path) pairs.push('Path=' + option.path); 
        if (option.expires) pairs.push('Expires=' + option.expires); 
        if (option.httpOnly) pairs.push('HttpOnly'); 
        if (option.secure) pairs.push('Secure'); 
        return pairs.join('; '); 
    } 
    module.exports = function (req, res) { 
        req.cookies = parseCookie(req.headers.cookie); 
        var id = req.cookies[sessionKey]; 
        if (!id) { 
            req.session = generate(); 
        } else { 
            var session = sessions[id]; 
            if (session) { 
                if (session.cookies.expire > Date.now()) { 
                    session.cookies.expire = Date.now() + EXPIRES; 
                    req.session = session; 
                } else { 
                    delete sessions[id]; 
                    req.session = generate(); 
                } 
            } else { 
                req.session = generate(); 
            } 
        } 
        for (var key in sessions) { 
            if (sessions[key].cookies.expire < Date.now()) { 
                delete sessions[key]; 
            } 
        } 
        var writeHead = res.writeHead; 
        res.writeHead = function () { 
            delete req.cookies[ham_sessionKey]; 
            var sessionStr = serialize(ham_sessionKey, req.session.id); 
            res.setHeader('Set-Cookie', serializeCookies(req.cookies).concat(sessionStr)); 
            return writeHead.apply(res, arguments); 
        } 
    }

第五步,模版渲染

这是最简单的。

第六步,数据库处理

这里可以是用一些ORM框架。

第七步,文件上传,post

第八步,就是你把上面的代码组织起来。

ji...9@sina.com
2016-12-16 · 超过197用户采纳过TA的回答
知道小有建树答主
回答量:462
采纳率:0%
帮助的人:261万
展开全部
首先安装express模块,cd到文件夹中,使用npm install express命令安装express module后,会发现文件夹中多了node_modules目录,里边会有express模块了。
进入到任意一个文件夹,执行express app命令,就会创建一个app的应用项目,结构如下:
E:\nodejs\express_demo>express app

create : app
create : app/package.json
create : app/app.js
create : app/public
create : app/bin
create : app/bin/www
create : app/public/stylesheets
create : app/public/stylesheets/style.css
create : app/views
create : app/views/index.jade
create : app/views/layout.jade
create : app/views/error.jade
create : app/public/images
create : app/routes
create : app/routes/index.js
create : app/routes/users.js
create : app/public/javascripts

install dependencies: (这里指示安装必备的包)
$ cd app && npm install

run the app: (这里指示执行,使用npm start)
$ DEBUG=app ./bin/www

cd进入app文件夹中,执行app,使用命令node app这时候会报错,因为第一次使用express框架的话,缺少很多必备的modules
报错:

module.js:340
throw err;
^
Error: Cannot find module 'serve-favicon'//表示缺少serve-favicon模块
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (E:\nodejs\Node.js寮€鍙戝疄鎴榎chapter_two\express_dem
o\app\app.js:3:15)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)

这个时候根据提示,安装必备的modules就可以了,如图
Your environment has been set up for using Node.js 0.10.26 (ia32) and npm.

C:\Users\Administrator>e:

E:\>cd nodejs

E:\nodejs>npm install serve-favicon
serve-favicon@2.2.0 node_modules\serve-favicon
├── ms@0.7.0
├── parseurl@1.3.0
├── fresh@0.2.4
└── etag@1.5.1 (crc@3.2.1)

E:\nodejs>npm install morgan
morgan@1.5.1 node_modules\morgan
├── basic-auth@1.0.0
├── depd@1.0.0
├── debug@2.1.1 (ms@0.6.2)
└── on-finished@2.2.0 (ee-first@1.1.0)

E:\nodejs>npm install cookie-parser
cookie-parser@1.3.3 node_modules\cookie-parser
└── cookie-signature@1.0.5

E:\nodejs>npm install body-parser
body-parser@1.12.0 node_modules\body-parser
├── content-type@1.0.1
├── raw-body@1.3.3
├── bytes@1.0.0
├── depd@1.0.0
├── qs@2.3.3
├── iconv-lite@0.4.7
├── on-finished@2.2.0 (ee-first@1.1.0)
├── debug@2.1.1 (ms@0.6.2)
└── type-is@1.6.0 (media-typer@0.3.0, mime-types@2.0.9)

E:\nodejs>

安装完成所有必备的modules后,在此执行app,项目根目录下npm start命令,如果还是提示类似Error: Cannot find module 'jade'错误的话,继续安装必备的模块

6
以上所有的一切完成后,在浏览器下输入http://127.0.0.1:3000/,如下图就表示成功了。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式