Node.JS从相识到相知--徒手搭建简易版json服务


声明:本文转载自https://my.oschina.net/u/3435444/blog/1622512,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

大家好!这是首次发有关NodeJS的文章,希望能对大家有所帮助。Node.JS对于追逐全栈开发的小伙伴们自然不陌生。他是建立与chrome V8引擎下的高性能,异步IO、事件驱动javascript语言,使编写高性能Web服务轻而易举。

今天要分享的是一个使用Node.JS逐步推演建立一个完善的json服务的过程。通过对代码逐步完善来介绍Node.JS的特点及执行流程。闲话少许,进入正题。 业务场景描述:监听指定端口,分析请求url,返回对应的图片目录或图片文件列表。


Round 1:搭建json服务 监听8000端口 
var _http=require("http"); var _url=require("url"); var _fs=require("fs");  /**  * test res show message is success!  */  var _server=_http.createServer((req,res)=>{  	console.log("json webservice is running\n");  	res.end("hello accp!");  });  _server.listen(8000);   

已上代码实现监听本地8000端口,当通过浏览器访问时,即可触发对应代码

输入图片说明


Round 2 : 返回json格式数据 
/**  *   * @authors Your Name (you@example.org)  * @date    2018-02-21 14:37:10  * @version $Id$  */   var _http=require("http"); var _url=require("url"); var _fs=require("fs");   /**  * test res show json message is success!  */  var  _server=_http.createServer((req,res)=>{  	console.log("json sebservice is running!\n"); 	  	res.writeHead(200,{'Content-Type':'text/json'});  	var out={ 		err:null, 		data:{ 			showMessage:"hello world" 		} 	};  	res.end(JSON.stringify(out));  });  _server.listen(8000);   

输入图片说明


Round 3:测试 json webservice 输出 文件夹列表 列表 
/**  *   * @authors Your Name (you@example.org)  * @date    2018-02-21 14:44:34  * @version $Id$  */   var _http=require("http"); var _url=require("url"); var _fs=require("fs");   /**  * 测试 json webservice 输出 文件夹列表  */  var _server=_http.createServer((req,res)=>{  	console.log("json webservice is running!\n");  	var out={};  	load_image_list((err,files)=>{ 		if(err){ 			res.writeHead(403,{ 				"Content-Type":"text/json; charset=utf-8"  			}); 			out={err:err,data:{}}; 			res.end(JSON.stringify(out)); 			return; 		} 		//指定 返回字符串编码 		res.writeHead(200,{ 			"Content-Type":"text/json; charset=utf-8" 		}); 		out={err:err,data:{imageList:files}}; 		res.end(JSON.stringify(out),'utf-8'); 		return;   	}); 	//http://nodejs.cn/api/fs.html#fs_fs_readdir_path_options_callback 	 });  /**  * 初始化 图片列表 返回 指定图片文件夹列表  * bug 未对目录下 文件类型进行判断 同时返回 当前目录下 所有文件类型  * @param  {Function} callback 回调函数  *  * @return {[type]}            [description]  */ var load_image_list=function(callback){  	_fs.readdir("images/",(err,files)=>{ 		if(err){ 			callback(err); 			console.log("load_image_list try exception!\n"); 			return; 		}  		callback(null,files); 	});  };   _server.listen(8000);  

输入图片说明 这里可以看到load_image_list方法注释内容提到,当前代码存在一定的漏洞,如果当前文件夹目录下存在图片文件,在返回结果时也会返回如图3-2。针对此bug修改load_image_list。

**  * 初始化 图片列表 返回 指定图片文件夹列表  * 增加 对指定目录下 文件类型的判断 只返回 文件夹  * @param  {Function} callback 回调函数  *  * @return {[type]}            [description]  */ var load_image_list=function(callback){  	_fs.readdir('images/',(err,files)=>{  		if(err){ 			console.log("load image list throw exception!\n");  			callback(err);  			return; 		} 		var only_dir=[]; 		//创建 匿名方法 通过递归方式 将异步判断 变更为 同步判断 		 		(function rtnPathIsDirList(index){ 			if(index==files.length){ 				callback(null,only_dir); 				return; 			} 			_fs.stat("images/"+files[index], (err,stats)=>{ 				if(err){ 					console.log("load image list check file type throw exception!\n");  					callback(err);  					return; 				}  				if(stats.isDirectory()){  					only_dir.push(files[index]);   				}  				rtnPathIsDirList(index+1);  				return; 			}); 		})(0);  	});  };  

输入图片说明

Round 4 :增加 路由器 功能 针对 传递进来的 url进行 分析  
/**  *   * @authors Your Name (you@example.org)  * @date    2018-02-21 15:01:25  * @version $Id$  */   var _http=require("http"); var _url=require("url"); var _fs=require("fs"); /**  * 测试 json webservice 输出 文件夹列表  * 增加 路由器 功能 针对 传递进来的 url进行 分析   * 增加 加载 图片列表 文件目录 输入  */   var _url=require('url'); var _server=_http.createServer((req,res)=>{  	console.log("json webservice is running!\n");  	var out={};  	//增加 请求 url 的分析 	console.log(req.url); 	var urlValue=req.url; 	var urlLength=urlValue.length; 	//console.log("urlValue.substr(1,11)"+urlValue.substr(1,11));  	//排除 浏览器 发起的 获取 图标请求 	if(urlValue=="/favicon.ico"){ 		console.log("web brower favicon request!\n"); 		res.end(); 		return; 	}  	if(urlValue=="/images.json"){ 		//获取 根目录 文件夹列表 		console.log("load images list is running!\n"); 		handle_list_image(req,res,urlValue.substr(1,6)+"/"); 		return; 	}else if(urlValue.substr(1,6)=="images"&&urlValue.substr(urlLength-4)=="json"){ 		//加载 某一个 目录下 的文件 		 		console.log("load image path:"+urlValue.substr(1,urlValue.length-6)); 		handle_list_imageFile(req,res,urlValue.substr(1,urlValue.length-6)+"/"); 		return; 	}else{ 		//无正常 数据 加载 返回404 错误。 		sendFailMessage(404,"请求页面不存在",res); 		console.log("error"); 		return;  	}   	 	//http://nodejs.cn/api/fs.html#fs_fs_readdir_path_options_callback 	 });   /**  * 获取图片列表  * 增加加载图片列表路径参数  * 将返回成功信息和失败信息进行封装  *  * @param  {[type]} req [description]  * @param  {[type]} res [description]  * @param  {[string]} filePath [加载更目录]   *  * @return {[type]}     [description]  */ var handle_list_image=function(req,res,filePath){  	load_image_list(filePath,(err,files)=>{ 		if(err){ 			// res.writeHead(403,{ 			// 	"Content-Type":"text/json; charset=utf-8"  			// }); 			// out={err:err,data:{}}; 			// res.end(JSON.stringify(out)); 			sendFailMessage(403,err,res); 			return; 		} 		//指定 返回字符串编码 		 		// res.writeHead(200,{ 		// 	"Content-Type":"text/json; charset=utf-8" 		// }); 		// out={err:null,data:{imageList:files}}; 		// res.end(JSON.stringify(out),'utf-8'); 		//  		var data={imageList:files}; 		sendSuccessMessage(data,res); 		return; 	}); };   /**  * 获取文件 图片文件列表  *  * @param  {[type]} req      [description]  * @param  {[type]} res      [description]  * @param  {[type]} filePath [description]  *  * @return {[type]}          [description]  */ var handle_list_imageFile=function(req,res,filePath){  	load_imageFile_list(filePath,(err,files)=>{ 		if(err){ 			// res.writeHead(403,{ 			// 	"Content-Type":"text/json; charset=utf-8"  			// }); 			// out={err:err,data:{}}; 			// res.end(JSON.stringify(out)); 			sendFailMessage(403,err,res); 			return; 		} 		//指定 返回字符串编码 		 		// res.writeHead(200,{ 		// 	"Content-Type":"text/json; charset=utf-8" 		// }); 		// out={err:null,data:{imageList:files}}; 		// res.end(JSON.stringify(out),'utf-8'); 		//  		var data={imageList:files}; 		sendSuccessMessage(data,res); 		return; 	}); };  /**  * 返回成功信息  *  * @param  {json} dataContent 返回数据json信息  * @param  {response} res         [description]  *  * @return {[type]}             [description]  */ var sendSuccessMessage=function(dataContent,res){ 	//指定 返回字符串编码 	res.writeHead(200,{ 		"Content-Type":"text/json; charset=utf-8" 	}); 	out={err:null,data:dataContent}; 	res.end(JSON.stringify(out),'utf-8'); }  /**  * 返回失败信息  *  * @param  {int} code 失败代码  * @param  {error} err  [description]  * @param  {[type]} res  [description]  *  * @return {[type]}      [description]  */ var sendFailMessage=function(code,err,res){ 	res.writeHead(code,{ 			"Content-Type":"text/json; charset=utf-8" 	}); 	out={err:err,data:{}}; 	res.end(JSON.stringify(out)); } /**  * 初始化 图片列表 返回 指定图片文件夹列表  * 增加 对指定目录下 文件类型的判断 只返回 文件夹  * 增加 遍历目录 变量	  * @param  {stinrg}   filePath 加载目录   * @param  {Function} callback 回调函数  *  * @return {[type]}            [description]  */ var load_image_list=function(filePath,callback){  	_fs.readdir(filePath,(err,files)=>{  		if(err){ 			console.log("load image list throw exception!\n");  			callback(err);  			return; 		} 		var only_dir=[]; 		//创建 匿名方法 通过递归方式 将异步判断 变更为 同步判断 		 		(function rtnPathIsDirList(index){ 			if(index==files.length){ 				callback(null,only_dir); 				return; 			} 			_fs.stat(filePath+files[index], (err,stats)=>{ 				if(err){ 					console.log("load image list check file type throw exception!\n");  					callback(err);  					return; 				}  				if(stats.isDirectory()){  					only_dir.push(files[index]);   				}  				rtnPathIsDirList(index+1);  				return; 			}); 		})(0);  	});  };   /**  * 初始化 图片列表 返回 指定图片文件列表  * 增加 对指定目录下 文件类型的判断 只返回 文件  * 增加 遍历目录 变量	  * @param  {stinrg}   filePath 加载目录   * @param  {Function} callback 回调函数  *  * @return {[type]}            [description]  */ var load_imageFile_list=function(filePath,callback){  	_fs.readdir(filePath,(err,files)=>{  		if(err){ 			console.log("load image file list throw exception!\n");  			callback(err);  			return; 		} 		var only_dir=[]; 		//创建 匿名方法 通过递归方式 将异步判断 变更为 同步判断 		 		(function rtnPathIsDirList(index){ 			if(index==files.length){ 				callback(null,only_dir); 				return; 			} 			_fs.stat(filePath+files[index], (err,stats)=>{ 				if(err){ 					console.log("load image list check file type throw exception!\n");  					callback(err);  					return; 				}  				if(stats.isFile()&&files[index].substr(files[index].length-3,3)=="jpg"){ 					console.log("files[index]:"+files[index]); 					console.log("files[index].substr(files[index].length-3,3):"+files[index].substr(files[index].length-3,3)+"\n");  					only_dir.push(files[index]);   				} 				  				rtnPathIsDirList(index+1);  				return; 			}); 		})(0);  	});  };    _server.listen(8000);  

这里主要是增加了路由的功能,测试访问路径如下:

  1. http://localhost:8000 返回结果如图; 输入图片说明
  2. http://localhost:8000/images.json 返回结果如图; 输入图片说明
  3. http://localhost:8000/images/image1.json 返回结果如图; 输入图片说明

本文发表于2018年02月22日 10:31
(c)注:本文转载自https://my.oschina.net/u/3435444/blog/1622512,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1920 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1