一、特点
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

node16对应yarn node 1_Server

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方式

十二、正则