nodejs

nodeJS

1.安装nodejs
从nodejs官网下载最新版本的node,设置环境变量这样就可以在cmd下直接用命令行操作npm
环境变量:path  d:/nodejs
查看本机node及npm版本

 

 
2.从官网上直接拷一个小脚本:
新建nodeExample.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});
server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

可以通过控制台直接运行:

打开浏览器输入http://127.0.0.1:3000/,页面上出现Hello World
如果将Hello World改成Hello NodeJs,刷新浏览器发现页面还是没变,此时要再次在控制台再次运行该js文件,Ctrl+C结束上次活动
 
函数篇
看一个本地函数nodeExample.js
var http=require('http');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        fun1(response);
        response.end();
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
function fun1(res){
    console.log('fun1');
    res.write("hello,this is fun1");
}
如果是别的地方引用的函数
新建function2.js
function fun2(res){
    console.log('fun2');
    res.write('hello,this is fun2');
}
module.exports=fun2;

nodeExample.js修改为

var http=require('http');
var otherFun=require("./function2.js");
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        fun1(response);
        otherFun(response);
        response.end();
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
function fun1(res){
    console.log('fun1');
    res.write("hello,this is fun1");
}

控制台使用node命令执行nodeExample.js

 

支持多个函数:
function2.js
module.exports={
    fun2:function(res){
        console.log('fun2');
        res.write('hello,this is fun2');
    },
    fun3:function(res){
        console.log('fun3');
        res.write('hello,this is fun3');
    }
}

nodeExample.js

var http=require('http');
var otherFun=require("./function2.js");
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        otherFun.fun2(response);
        otherFun.fun3(response);
        response.end();
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');

调用时也可以这样:otherFun['fun3'](response);
也可以这样:
funname='fun3';
otherFun[funname ](response);
 
调用模块
创建User.js
function User(id,name,age){
    this.id=id;
    this.name=name;
    this.age=age;
    this.enter=function(){
        console.log(this.name+'进入图书馆');
    }
}
module.exports=User;

nodeExample.js

var http=require('http');
var User=require("./User.js");
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        user=new User(1,"张三",20);
        user.enter();
        response.end();
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');

运行,再增加Teacher.js

var User=require('./User');
function Teacher(id,name,age){
    User.apply(this,[id,name,age]);
    this.teach=function(res){
        res.write(this.name+"讲课");
    }
}
module.exports=Teacher;

nodeExample.js

var http=require('http');
var Teacher=require("./Teacher");
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        teacher=new Teacher(1,"张三",20);
        teacher.enter();
        teacher.teach(response);
        response.end();
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/'
 

 

 
路由
var http=require('http');
var url=require('url');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        console.log(pathname);
        response.end();
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
在浏览器在Url地址后加上login,结果:
如果不想要/,可以通过正则去掉
var http=require('http');
var url=require('url');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        //替换掉前面的/
        pathname=pathname.replace(/\//,'');
        console.log(pathname);
        response.end();
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
 
 
新建route.js
module.exports={
    login:function(req,res){
        res.write("this is login method!");
    },
    zhuce:function(req,res){
        res.write("This  is zhuce method");
    }
}

nodeExample.js

var http=require('http');
var url=require('url');
var route=require('./route');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        //替换掉前面的/
        pathname=pathname.replace(/\//,'');
        console.log(pathname);
        route[pathname](request,response);
        response.end();
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');

如果浏览器上输入其他url地址,后台就会报错:
 
 
读文件
同步方式读取文件
创建openFile.js
var fs=require('fs');
module.exports={
    readFileSync:function(path){
        var data=fs.readFileSync(path,'utf-8');
        console.log(data);
        console.log("同步方法执行完毕");
    }
}

nodeExample.js

var http=require('http');
var openFile=require('./openFile');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        //这里的path是相对于openFile.js路径的
        openFile.readFileSync('./login.html');
        response.end();
        console.log('主程序执行完毕');
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
在跟openFile.js文件相同的路径下创建login.html,该html中只有 登录成功 四个字
在控制台执行命令:
 
异步方式读取文件
openFile.js修改为:
var fs=require('fs');
module.exports={
    readFile:function(path){
        fs.readFile(path,function(err,data){
            if(err){
                console.log(err);
            }else{
                console.log(data.toString());
            }
        });
        console.log("异步方式执行完毕");
    }
}

nodeExample.js

var http=require('http');
var openFile=require('./openFile');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        openFile.readFile('./login.html');
        response.end('ok');
        console.log('主程序执行完毕');
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
也就是说,程序执行到fs.readFile()这个函数时,这个函数还没有执行完,程序自动往下走,先读出了console.log("异步方式执行完毕");
如果将程序openFile.js改为:
var fs=require('fs');
module.exports={
    readFile:function(path,res){
        fs.readFile(path,function(err,data){
            if(err){
                console.log(err);
            }else{
                console.log(data.toString());
                res.write(data);
            }
        });
        console.log("异步方式执行完毕");
    }
};
nodeExample.js相应的修改函数:openFile.readFile('./login.html',response);
主要的问题是,openFile.readFile('./login.html',response);这个函数还没有执行完,response.end('ok');就已经执行完了
可以用闭包开解决:
nodeExample.js
var http=require('http');
var openFile=require('./openFile');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;chaeset=utf-8'});
    if(request.url!="/favicon.ico"){
        function recall(data){
            response.write(data);
            response.end('ok');
        }
        openFile.readFile('./login.html',recall);
        console.log('主程序执行完毕');
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
openFile.js
var fs=require('fs');
module.exports={
    readFile:function(path,recall){
        fs.readFile(path,function(err,data){
            if(err){
                console.log(err);
            }else{
                console.log(data.toString());
                recall(data);
            }
        });
        console.log("异步方式执行完毕");
    }
};
执行过程:执行到openFile.readFile()函数时,开个内存执行该函数,另一个继续往下执行函数之后的程序,先把能执行的给执行,不能立刻执行的继续执行
 
 
将之前的路由修改为:
nodeExample.js
var http=require('http');
var url=require('url');
var route=require('./route.js');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        pathname=pathname.replace(/\//,'');
        route[pathname](request,response);
    }
}).listen(8000);
console.log('server running at http://127.0.0.1:8000/');
route.js
var openFile=require('./openFile');
module.exports={
    login:function(req,res){
        function recall(data){
            res.write(data);
            res.end();
        }
        openFile.readFile('./login.html',recall);
    }
}
openFile.js
var fs=require('fs');
module.exports={
    readFile:function(path,recall){
        fs.readFile(path,function(err,data){
            if(err){
                console.log(err);
            }else{
                console.log(data.toString());
                recall(data);
            }
        });
        console.log("异步方式执行完毕");
    }
};

程序首先得到了pathname,如login,转到login函数,执行openFile.readFile()函数,将login.html读取出来,并将读取的内容通过recall函数写出来
 
写文件
也有同步跟异步两种方式
新增writeFile.js
var fs=require('fs');
module.exports={
    writeFile:function(path,data,recall){
        fs.writeFile(path,data,function(err){
            if(err){
                throw err;
            }
            console.log('This file is saved');
            recall('write file success');
        });
    },
    writeFileSync:function(path,data){
        fs.writeFileSync(path,data);
        console.log('同步写文件成功');
    }
}
route.js
var openFile=require('./openFile');
var writeFile=require('./writeFile')
module.exports={
    login:function(req,res){
        function recall(data){
            res.write(data);
            res.end();
        }
        openFile.readFile('./login.html',recall);
    },
    writeFile:function(req,res){
        function recall(data){
            res.write(data);
            res.end();
        }
        writeFile.writeFile('./one.txt','我的写入文件',recall)
    }
}
nodeExample.js
var http=require('http');
var url=require('url');
var route=require('./route.js');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/html;chaeset=utf-8'});
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        pathname=pathname.replace(/\//,'');
        route[pathname](request,response);
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');

成功之后打开one.txt可以看到    我的写入文件
 
 
读取图片
nodeExample.js
var http=require('http');
var openFile=require('./openFile.js');
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'image/jpeg'});
    if(request.url!="/favicon.ico"){
        openFile.readImg('./image.png',response);   
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
openFile.js
var fs=require('fs');
module.exports={
    readImg:function(path,res){
        fs.readFile(path,'binary',function(err,file){
            if(err){
                console.log(err);
                return;
            }else{
                console.log('输出文件');
                res.write(file,'binary');
                res.end();
            }
        })
    }
};

如果加上文字,就会报错,如:
if(request.url!="/favicon.ico"){
        response.write('hello world');
        openFile.readImg('./image.png',response);   
    }
此时图片就无法显示
 
 
再写路由的一个例子,解决这个问题
nodeExample.js
var http=require('http');
var url=require('url');
var route=require('./route.js');
http.createServer(function(request,response){
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        pathname=pathname.replace(/\//,'');
        route[pathname](request,response);
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');
route.js
var openFile=require('./openFile');
module.exports={
    login:function(req,res){
        res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
        function recall(data){
            res.write(data);
            res.end();
        }
        openFile.readFile('./login.html',recall);
    },
    showImg:function(req,res){
        res.writeHead(200,{'Content-Type':'image/jpeg'});
        openFile.readImg('./image.png',res);
    }
}
openFile.js
var fs=require('fs');
module.exports={
    readFile:function(path,recall){
        fs.readFile(path,function(err,data){
            if(err){
                console.log(err);
            }else{
                console.log(data.toString());
                recall(data);
            }
        });
        console.log("异步方式执行完毕");
    },
    readImg:function(path,res){
        fs.readFile(path,'binary',function(err,file){
            if(err){
                console.log(err);
                return;
            }else{
                console.log('输出文件');
                res.write(file,'binary');
                res.end();
            }
        })
    }
};
login.html
<html>
<head>
</head>
<body>
登录界面
<img src="./showImg">
</body>
</html>

 

 

异常处理
如果请求路径不正确,后台就会报错,对异常进行处理,将上面的例子中的nodeExample.js修改为:

 

ar http=require('http');
var url=require('url');
var route=require('./route.js');
http.createServer(function(request,response){
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        pathname=pathname.replace(/\//,'');
        try{
            route[pathname](request,response);
            console.log('..............');
        }catch(err){
            console.log('error is:'+err);
            response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
            response.write(err.toString());
            response.end();
        }
        console.log('server finish');
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');

从结果可以发现:route[pathname](request,response);执行报错后,console.log('..............');并没有执行
如果请求的url是正确的,但是readFile()方法读取文件的路径是错误的,那么如何处理这种异常呢
nodeExample.js
var http=require('http');
var url=require('url');
var route=require('./route.js');
http.createServer(function(request,response){
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        pathname=pathname.replace(/\//,'');
        try{
            route[pathname](request,response);
            console.log('..............');
        }catch(err){
            console.log('aaaa:'+err);
            response.writeHead(200,{'Content-Type':'text/html;chaeset=utf-8'});
            response.write(err.toString());
            response.end();
        }
        console.log('server finish');
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');

route.js

var openFile=require('./openFile');
module.exports={
    login:function(req,res){
        res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
        function recall(data){
            res.write(data);
            res.end();
        }
        openFile.readFile('./log.html',recall);
    }
}

openFile.js

var fs=require('fs');
module.exports={
    readFile:function(path,recall){
        fs.readFile(path,function(err,data){
            if(err){
                console.log("bbbb:"+err);
            }else{
                console.log(data.toString());
                recall(data);
            }
        });
        console.log("异步方式执行完毕");
    }
};

浏览器上输入网址:http://127.0.0.1:8000/login,发现该页面一直在加载(主要是没有执行到recall方法,也就没有执行到response.end()方法,所以页面响应一直无法结束),后台如下:

 

nodejs和java在异常处理方面是不一样的,如果异步时发生异常,是无法在主程序捕获的,上例中异步发生异常是时程序是可以执行到console.log('..............'); 这一步的,所以必须在异步的地方处理异常,将openFile.js修改为:

var fs=require('fs');
module.exports={
    readFile:function(path,recall){
        fs.readFile(path,function(err,data){
            if(err){
                console.log("bbbb:"+err);
                recall('file not exist');
            }else{
                console.log(data.toString());
                recall(data);
            }
        });
        console.log("异步方式执行完毕");
    }
};

也就是说,我们要在出现错误的openFile.js里处理异常
我们也可以专门写一个异常类,将异常抛出,增加Exception.js
module.exports={
    expfun:function(flag){
        if(flag==0){
            throw '我是例外';
        }
        return 'success';
    }
}

nodeExample.js

var http=require('http');
var url=require('url');
var route=require('./route.js');
var exception=require('./exception')
http.createServer(function(request,response){
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        pathname=pathname.replace(/\//,'');
        try{
            data=exception.expfun(10);
            response.write(data);
            response.end();
        }catch(err){
            console.log('aaaa:'+err);
            response.writeHead(200,{'Content-Type':'text/html;chaeset=utf-8'});
            response.write(err.toString());
            response.end();
        }
        console.log('server finish');
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');

将nodeExample.js中修改为:data=exception.expfun(0);

 

 

 
参数接收
以get方式
nodeExample.js
http=require('http');
var url=require('url');
var route=require('./route.js');
http.createServer(function(request,response){
    if(request.url!="/favicon.ico"){
        var pathname=url.parse(request.url).pathname;
        pathname=pathname.replace(/\//,'');
        try{
            route[pathname](request,response);
            console.log('..............');
        }catch(err){
            console.log('aaaa:'+err);
            response.writeHead(200,{'Content-Type':'text/html;chaeset=utf-8'});
            response.write(err.toString());
            response.end();
        }
        console.log('server finish');
    }
}).listen(8000);
console.log('serer running at http://127.0.0.1:8000/');

修改login.html

<html>
<head>
</head>
<body>
登录界面
<img src="./showImg">
<form action="./login" method="get">
    <table align="center">
        <tr>
            <td>email:</td>
            <td><input type="text" name="email"/></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input type="password" name="pwd"/></td>
        </tr>
        <tr>
            <td align="center"><input type="submit" value="登录" /></td>
        </tr>
</form>
</body>
</html>

route.js

var openFile=require('./openFile');
var url=require('url');
function getRecall(req,res){
    res.writeHead(200,{'Content-Type':'text/html;chaeset=utf-8'});
    function recall(data){
        res.write(data);
        res.end();
    }
    return recall;
}
module.exports={
    login:function(req,res){
        //get方式接收参数
        var rdata=url.parse(req.url,true).query;
        console.log(rdata);
        if(rdata['email']!=undefined){
            console.log(rdata['email']);
            console.log(rdata['pwd']);
        }
        recall=getRecall(req,res);
        openFile.readFile('./login.html',recall);
    },
    showImg:function(req,res){
        res.writeHead(200,{'Content-Type':'image/jpeg'});
        openFile.readImg('./image.png',res);
    }
}

openFile.js

var fs=require('fs');
module.exports={
    readFile:function(path,recall){
        fs.readFile(path,function(err,data){
            if(err){
                console.log("bbbb:"+err);
                recall('file not exist');
            }else{
                console.log(data.toString());
                recall(data);
            }
        });
        console.log("异步方式执行完毕");
    },
    readImg:function(path,res){
        fs.readFile(path,'binary',function(err,file){
            if(err){
                console.log(err);
                return;
            }else{
                console.log('输出文件');
                res.write(file,'binary');
                res.end();
            }
        })
    }
};

后台也可以捕获到,这里的rdata就是一个对象

 
 
以post方式
将route.js修改为:
var openFile=require('./openFile');
var url=require('url');
var querystring=require('querystring');//post需导入
function getRecall(req,res){
    res.writeHead(200,{'Content-Type':'text/html;chaeset=utf-8'});
    function recall(data){
        res.write(data);
        res.end();
    }
    return recall;
}
module.exports={
    login:function(req,res){
        //post方式接收参数
        //定义一个post变量,用于暂存请求体的信息
        var post='';
        //通过req的data事件监听函数,每当接收到请求体的数据,就存到post变量中
        req.on('data',function(chunk){
            post+=chunk;
        });
        //在end事件触发后,通过querystring.parse将poset解析为真正的post格式,然后向客户端返回
        req.on('end',function(){
            post=querystring.parse(post);
            console.log('接收参数:'+post['email']+'\n');
            console.log('接收参数:'+post['pwd']+'\n');
        })
        recall=getRecall(req,res);
        openFile.readFile('./login.html',recall);
    },
    showImg:function(req,res){
        res.writeHead(200,{'Content-Type':'image/jpeg'});
        openFile.readImg('./image.png',res);
    }
}
将login.html的提交方式改为post
输入email和密码提交之后:

post方式是异步的,因为要拿到所有的请求信息后才能进行处理

 
 
 
 
 

posted @ 2017-02-24 17:43  LittleMoon  阅读(196)  评论(0编辑  收藏  举报