一、特点
1、node是单线程,异步加载,只有一个线程,在内存另外开一个空间
2、特点:速度快,占内存,百万级并发未优化的情况下,1M的链接消耗16G内存
3、事件驱动(理解为异步回调)
二、简单的配置以及hello word
测试是否安装完成
npm -v
node -v
打印hello word
1、建立文件 n1_node.js
console.log('hello word');
2、按住shift右键,在此处打开命令窗口,输入 node n1_node.js,在后台输出console
3、这只是后台输出,如果起服务,输出hello word
var http = require('http'); //通过require引用nodejs自带的'http'模块并赋值给http
http.createServer(function(request,response){ //http创建了一个服务,两个参数,一个是浏览器发出的请求对象,一个是服务器写回的对象
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'}); //写入协议头
if(request.url!='/favicon.ico'){ //清除第二次访问
console.log('df');
response.write('hello word');
response.end(''); //协议结束
}
}).listen(8088); //监听8088端口
console.log('Server running at http://127.0.0.1:8000/'); //这里的打印是服务端的
三、调用函数
1、调用本地函数
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(8088);
function fun1(res){ //调用本地函数
console.log('fun1')
res.write('dd');
};
2、调用其他js
otherfun2.js (仅一个函数调用)
function fun2(res){
console.log('fun2')
res.write('ee');
};
module.exports = fun2; //只支持一个函数调用,暴露此函数
var http = require('http');
var otherfun2 = require('./otherfun2.js'); //调用外部js
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
if(request.url!='/favicon.ico'){
//fun1(response);
otherfun2(response); //调用外部js
response.end('');
};
}).listen(8088);
function fun1(res){ //调用本地函数
console.log('fun1')
res.write('dd');
};
otherfun2.js (多个函数调用)
module.exports = { //写成这种形式
fun2:function(res){
console.log('fun2')
res.write('ee');
},
fun3:function(res){
console.log('fun3')
res.write('ff');
}
};
var http = require('http');
var otherfun2 = require('./otherfun2.js'); ////调用外部js
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
if(request.url!='/favicon.ico'){
//fun1(response);
otherfun2.fun2(response); //调用的时候加点
response.end('');
};
}).listen(8088);
function fun1(res){ //调用本地函数
console.log('fun1');
res.write('dd');
};
四、模块调用(实例化继承调用)
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; //暴露出去
teach.js
var User=require('./user.js');
function Teacher(id,name,age){
User.apply(this,[id,name,age]); //继承过来
this.teachs=function(res){
res.write(this.name+'是老师');
}
};
module.exports=Teacher;
n3_node.js
var http = require('http');
var Teach=require('./teach.js');
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
if(request.url!='/favicon.ico'){
Tea=new Teach(1,'张三',23); //实例化
Tea.enter(); //调用user方法
Tea.teachs(response); //调用自身方法
response.end('');
};
}).listen(8088);
console.log('Server running at http://127.0.0.1:8000/');
五、路由初步
//思路,先截出根目录后的地址,在根据地址名称来访问不同的函数(方法名==地址名)
router.js
module.exports={
login:function(req,res){
res.write('我是login方法');
},
zhuce:function(req,res){
res.write('我是注册方法');
}
}
n4_node.js
var http = require('http');
var url = require('url'); //url是内部对象
var router = require('./router');
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); //http://localhost:8088后台打出一个/,表明在根目录下,http://localhost:8088/ssp,后台打印出/ssp
pathname=pathname.replace(/\//,''); //替换掉/
console.log(pathname);
router[pathname](request,response); //通过[]传入方法名
response.end('');
};
}).listen(8088);
console.log('Server running at http://127.0.0.1:8000/');
六、读文件
(1)、同步读取
optfile.js
var fs=require('fs'); //node自带fs,是为了操作文件的
module.exports={ //同步读取
readfileSync:function(path,rs){
var data=fs.readFileSync(path,'utf-8'); //fs.readFileSync是fs里面的方法
rs.write(data); //这里页面打印
console.log('同步方法执行完成');
}
}
n5_node.js
var http = require('http');
var optfile = require('./optfile.js');
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
if(request.url!='/favicon.ico'){
optfile.readfileSync('./logoin.html',response); //同步操作
response.end('');
console.log('主文件执行完毕');
};
}).listen(8088);
console.log('Server running at http://127.0.0.1:8000/');
(2)、异步读取
optfile.js
var fs=require('fs'); //node自带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); //不能直接输出recall.write(data),借用闭包方法,这里的recall是一个方法,写在了no5_node.js中
}
});
console.log('异步方法执行完成');
}
}
n5_node.js
var http = require('http');
var optfile = require('./optfile.js');
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
if(request.url!='/favicon.ico'){
function recall(data){ //这里传入data
response.write(data);
response.end(''); //异步完了以后,结束
};
optfile.readfile('./logoin.html',recall); //异步操作,传入recall,会到optfile.js中去调用
console.log('主文件执行完毕');
};
}).listen(8088);
console.log('Server running at http://127.0.0.1:8000/');
七、写文件
otherfun.js
var fs= require('fs');
module.exports={
writefile:function(path,data,recall){ //异步方式
fs.writeFile(path, data, function (err) {
if (err) {
throw err;
}
console.log('It\'s saved!'); //文件被保存
recall('写文件成功');
});
},
writeFileSync:function(path,data){ //同步方式
fs.writeFileSync(path, data);
console.log("同步写文件完成");
}
};
nodestuty.js
var http = require('http');
var otherfun = require('./otherfun.js');
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
if(request.url!='/favicon.ico'){
function recall(data){ //这里传入data
response.write(data);
response.end(''); //异步完了以后,结束
};
otherfun.writefile('./one.txt','bbb',recall); //异步操作,传入recall,会到optfile.js中去调用
console.log('主文件执行完毕');
};
}).listen(8088);
console.log('Server running at http://127.0.0.1:8088/');
八、读取图片
otherfun.js
var fs= require('fs');
module.exports={
readImg:function(path,res){
fs.readFile(path,'binary',function(err, file) { //binary二进制流的文件
if (err) {
console.log(err);
return;
}else{
console.log("输出文件");
//res.writeHead(200, {'Content-Type':'image/jpeg'});
res.write(file,'binary'); //发送格式是binary
res.end();
}
});
}
};
nodestuty.js
var http = require('http');
var otherfun = require('./otherfun');
http.createServer(function (request, response) {
//response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
response.writeHead(200, {'Content-Type':'image/jpeg'}); //二进制流的方式输出
if(request.url!=="/favicon.ico"){ //清除第2此访问
console.log('访问');
//response.write('hello,world');//不能向客户端输出任何字节
otherfun.readImg('./pig.png',response);
//------------------------------------------------
console.log("继续执行");
//response.end('hell,世界');//end在方法中写过
}
}).listen(8088);
console.log('Server running at http://127.0.0.1:8088/');
九、路由改造
nodestuty.js 调用路由,通过otherfun[pathname] 来跳转login.html页面
var http = require('http');
var url = require('url');
var otherfun = require('./otherfun');
http.createServer(function (request,response) {
if(request.url!=="/favicon.ico"){ //清除第2此访问
pathname=url.parse(request.url).pathname;
pathname = pathname.replace(/\//,'');//替换掉前面的/
otherfun[pathname](request,response);
}
}).listen(8088);
console.log('Server running at http://127.0.0.1:8088/');
login.html showImg地址,又去请求,调用otherfun.js中的showImg方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>abc</div>
<img src="./showImg" />
</body>
</html>
otherfun.js res.writeHead 区分文本和图片
var optfile = require('./optfile');
function getRecall(req,res){
res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
function recall(data){
res.write(data);
res.end('');//不写则没有http协议尾
}
return recall;
}
module.exports={
login:function(req,res){
recall = getRecall(req,res);
optfile.readfile('./login.html',recall);
},
showImg:function(req,res){
console.log(123)
res.writeHead(200, {'Content-Type':'image/jpeg'});
optfile.readImg('./pig.png',res);
}
}
optfile.js 包含从otherfun.js请求过来的两个方法
var fs=require('fs'); //node自带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); //不能直接输出recall.write(data),借用闭包方法,这里的recall是一个方法,写在了no5_node.js中
}
});
console.log('异步方法执行完成');
},
readImg:function(path,res){
fs.readFile(path,'binary',function(err, file) { //binary二进制流的文件
if (err) {
console.log(err);
return;
}else{
console.log("输出文件");
//res.writeHead(200, {'Content-Type':'image/jpeg'});
res.write(file,'binary'); //发送格式是binary
res.end();
}
});
}
};
十、异常处理
1、路由try catch 异步方式在路由中进行捕获
nodestuty.js 如果otherfun方法不正确,执行catch下的方法
var http = require('http');
var url = require('url');
var otherfun = require('./otherfun');
//var exception = require('./models/Exception');
http.createServer(function (request,response){
if(request.url!=="/favicon.ico"){ //清除第2此访问
pathname = url.parse(request.url).pathname;
pathname = pathname.replace(/\//,'');//替换掉前面的/
response.writeHead(200,{'Content-Type': 'text/html;charset=utf-8'});
try{
otherfun[pathname](request,response);
}catch(err){
console.log('aaaaa='+err);
response.write(err.toString());
}
response.end('');
console.log("server执行完毕");
}
}).listen(8088);
console.log('Server running at http://127.0.0.1:8088/');
otherfun.js
module.exports={
login:function(req,res){
res.write('我是login方法');
},
zhuce:function(req,res){
res.write('我是注册方法');
}
}
2、throw 跑出
nodestuty.js
var http = require('http');
var url = require('url');
//var otherfun = require('./otherfun');
var exception = require('./Exception');
http.createServer(function (request,response){
if(request.url!=="/favicon.ico"){ //清除第2此访问
pathname = url.parse(request.url).pathname;
pathname = pathname.replace(/\//,'');//替换掉前面的/
response.writeHead(200,{'Content-Type': 'text/html;charset=utf-8'});
try{
data = exception.expfun(10);
}catch(err){
console.log('aaaaa='+err);
response.write(err.toString());
}
response.end('');
console.log("server执行完毕");
}
}).listen(8088);
console.log('Server running at http://127.0.0.1:8088/');
Exception.js 直接用throw进行抛出
module.exports={
expfun:function(flag){
if(flag==0){
throw '我是例外';
};
return "success";
}
};
十一、参数接收
get提交方式
nodestuty.js
var http = require('http');
var url = require('url');
var router = require('./otherfun');
http.createServer(function (request,response){
if(request.url!=="/favicon.ico"){ //清除第2此访问
pathname=url.parse(request.url).pathname;
pathname=pathname.replace(/\//,'');//替换掉前面的/
try{
router[pathname](request,response);
}catch(err){
console.log('出错='+err);
response.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
response.write(err.toString());
response.end('');
}
console.log("server执行完毕");
}
}).listen(8088);
console.log('Server running at http://127.0.0.1:8088/');
otherfun.js
var optfile = require('./optfile');
var url = require('url');
function getRecall(req,res){
res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
function recall(data){
res.write(data);
res.end('');//不写则没有http协议尾
}
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);
optfile.readfile('./login.html',recall);
},
showImg:function(req,res){
res.writeHead(200, {'Content-Type':'image/jpeg'});
optfile.readImg('./pig.png',res);
}
}
optfile.js
var fs=require('fs'); //node自带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); //不能直接输出recall.write(data),借用闭包方法,这里的recall是一个方法,写在了no5_node.js中
}
});
console.log('异步方法执行完成');
},
readImg:function(path,res){
fs.readFile(path,'binary',function(err, file) { //binary二进制流的文件
if (err) {
console.log(err);
return;
}else{
console.log("输出文件");
//res.writeHead(200, {'Content-Type':'image/jpeg'});
res.write(file,'binary'); //发送格式是binary
res.end();
}
});
}
};
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</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><input type="submit" value="登录"></td>
</tr>
</table>
</form>
</body>
</html>
post提交方式
其他同上
otherfun.js
var optfile = require('./optfile');
var url = require('url');
var querystring = require('querystring'); //post需导入
function getRecall(req,res){
res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
function recall(data){
res.write(data);
res.end('');//不写则没有http协议尾
}
return recall;
}
module.exports={
login:function(req,res){
//-------post方式接收参数----------------
var post = ''; //定义了一个post变量,用于暂存请求体的信息
req.on('data',function(chunk){ //通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
post += chunk;
});
//-------注意异步-------------
req.on('end',function(){ //在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。
post = querystring.parse(post);
console.log('email:'+post['email']+'\n');
console.log('pwd:'+post['pwd']+'\n');
recall = getRecall(req,res);
optfile.readfile('./login.html',recall);
});
},
showImg:function(req,res){
res.writeHead(200, {'Content-Type':'image/jpeg'});
optfile.readImg('./pig.png',res);
}
}
另外把login.html中改为post方式
十二、正则