Node.js基础建站(一)

一,index.js页面

//模块一(服务模块):负责启动服务
//模块二(扩展模块):负责扩展req和res对象,为req和res增加以下更方便好用的API
//模块三(路由模块):负责路由判断
//模块四(业务模块):负责具体路由的业务代码
//模块五(数据操作模块):负责进行数据库操作
//模块六(配置模块):负责保存各种项目中用到的配置信息
//步骤:1:思考该模块要封装什么代码?2:思考这些代码有用到外部的数据吗,
//如果用到了,是否需要参数传入到模块中。3:当前模块对外需要暴露的东西(module.exports的值)

// 引入模板
var http=require('http');
var context=require('./context.js');
var router=require('./router.js');
var config=require('./config.js');

http.createServer(function(req,res){

    //调用context模块,为req和res加方法。
    context(req,res);
    router(req,res);
	 

}).listen(8080,function(){
  console.log('服务器启动了,请访问:http://localhost:'+config.port);
});

二,contex.js页面

相关知识补充:

//核心模块,,文件模块.json .js .node ,,自定义模块(第三方)
//情况一,参数是路径  require('./index.js')  ./表示js当前所在的目录    require('./index')先找js,没有找json,没有找node,
//没有然后找文件(package.json -> main入口文件app.js ->.js,.json,.node )
//情况二,参数不是路径是模块名称,先查找是否有该核心模块,若没有则找js文件所在目录下查找,若没有则一层一层往上找父目录里找
//直到磁盘根目录。
/**
// 声明一段代码的HTML文档
var html='<h2><%= name %></h2>';

//template() 函数的返回依然是个函数
var fn=_.template(html);
//fn接受一个数据对象,并用其替换html中的模板内容
 html=fn({name:'达达'});
console.log(html);
**/
//模块二(扩展模块):负责扩展req和res对象,为req和res增加以下更方便好用的API


  var url=require('url');
  var fs=require('fs');
  var mime=require('mime');
  var _=require('underscore');

  //让当前模块对外暴露一个函数,通过这个函数将index.js的req和res传递到当前这个模块。
  module.exports=function(req,res){
	  var urlObj=url.parse(req.url.toLowerCase(),true);
      req.method=req.method.toLowerCase();
	  req.query=urlObj.query;

	  res.pathname=urlObj.pathname;
	  console.log("res.pathname=urlObj.pathname:"+res.pathname);
      console.log("res.method:"+res.method);
	  res.render=function(filename,tplData){
		fs.readFile(filename,function(err,data){
		  if(err){
			res.writeHead(404,'Not Found',{'Content-Type':'text/html;charset=utf-8'});
			res.end('404,Not Found.');
			return;
		  }
		  
		  //如果用户传递了模板数据,则进行替换。
                  
		  if(tplData){
			var fn=_.template(data.toString('utf8'));
			data=fn(tplData);
		  }
		  res.setHeader('Content-Type',mime.getType(require.url));

		  // 把读到的数据发送
		  //res 是http.ServerResponse对象
		   res.end(data);
		 });
	  }
  }

三,router.js页面

//模块三(路由模块):负责路由判断
var url=require('url');
var path=require('path');
var handler=require('./handler.js');

module.exports=function(req,res){
  if(req.url==='/' || req.url.startsWith('/index') && req.method==='get'){
      
	  handler.index(req,res);

  }else if( req.url.startsWith('/list') && req.method==='get'){

      handler.list(req,res);
	  
  }else if(req.url.startsWith('/login') && req.method==='get'){

	  handler.loginGet(req,res);

  }else if(req.url.startsWith('/login') && req.method==='post'){
		
      handler.loginPost(req,res);

  }else{
		
      handler.elseurl(req,res);

  }

}

四,handler.js页面

//模块四(业务模块):负责具体路由的业务代码
var fs=require('fs');
var path=require('path');
var querystring=require('querystring');
var config=require('./config.js');


//这里的代码第一次加载该模块时会执行
//console.log(1);

//该模块负责最具体业务进行处理
module.exports.index=function(req,res){

    //这里的代码每次调用该方法时会被执行
    //console.log(1);

	//调用函数
	readNewsData(function(list_news){
	   res.render(path.join(__dirname,'index.html'),{list:list_news});
	});
}
module.exports.list=function(req,res){
   //读取相应id的内容
   readNewsData(function(list_item){
	   for(var i=0;i<list_item.length;i++){
	   if(list_item[i].id.toString()=== req.query.id){
		 var model=list_item[i];
		 break;
	   }
	  
	 }
	if(model){
	   res.render(path.join(__dirname,'list.html'),{item:model});
	 }else{
	   res.end('No Such Item');
	 }
	});
}
module.exports.loginGet=function(req,res){
	 //获取用户提交的数据,用url模块
	  
	 //防止data.json文件覆盖
	 readNewsData(function(list){
		//添加ID属性
		// urlObj.query.id=list.length;
		list.push(req.query);
		//把数据保存到data.json文件中
		writeNewsData(JSON.stringify(list),function(){
		  //设置响应报文头告诉浏览器进行跳转
			res.statusCode=302;
			res.statusMessage='Found';
			res.setHeader('Location','/');

			res.end();
		});
	 });
}
module.exports.loginPost=function(req,res){
	
    readNewsData(function(list){
	  postBodyData(req,function(postBody){
	   //添加ID属性
	   postBody.id=list.length+1;
	   list.push(postBody);
	   writeNewsData(JSON.stringify(list),function(){
		 //设置响应报文头告诉浏览器进行跳转
		 res.statusCode=302;
		 res.statusMessage='Found';
		 res.setHeader('Location','/');

		 res.end();
	  
		 });
	  });
	  
	});
}
module.exports.elseurl=function(req,res){
   //当url没有query请求字符串,可以直接跳转
   res.render(path.join(__dirname,req.url));
}


//封装一个写入data.json文件的函数
function writeNewsData(data,callback){
   fs.writeFile(config.dataPath,data,function(err){
		if(err){
		 throw err;
		}
		//调用callback来执行当写入数据完毕后的操作,可能不同
		callback();
	 });
}
//封装一个读取data.json文件的函数
function readNewsData(callback){
  fs.readFile(config.dataPath,'utf8',function(err,data){
	 //第一次读取文件不存在,则排除报错ENOENT
	 if(err && err.code!= 'ENOENT'){throw err;}
	 var list=JSON.parse(data || '[]');
     callback(list);
	 //函数内部有异步函数,需要本函数有一个回掉函数callback参数,来读取异步数据,然后传递出去
  });
}
//封装一个获取用户post提交的数据的方法
function postBodyData(req,callback){
    //把数据保存到data.json文件中
	// post提交数据会分多次,因此需要监听request事件的data事件,当request的end事件被调用
	// 表示数据提交接受完成。监听事件用on
	var array=[];//保存用户每次提交的数据
	req.on('data',function(chunk){
	 //chunk 参数,是浏览器提交的一部分数据,类型为Buffer
	  array.push(chunk);
	});
	req.on('end',function(){
	  //监听end事件,把array中的数据汇总,并转换为字符串
	  var postBody=Buffer.concat(array).toString('utf8');
	  // 把查询字符串转换为JSON对象eg:title=fffff&url=ndskjc&text=fcdsv
	  //如果是JSON类型的字符串(eg:{title:'fffff',url:'ndskjc',text:'fcdsv'})转为JSON对象用JSON.parse()方法
	  postBody=querystring.parse(postBody);
	  callback(postBody);
    });
}

五,config.js页面

//模块六(配置模块):负责保存各种项目中用到的配置信息
var path=require('path');

module.exports={
  "port":8080,
  "dataPath":path.json(__dirname,'data','data.json')
};

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值