当前位置: 首页 > 后端技术 > Node.js

无第三方依赖的手写Node-Server

时间:2023-04-04 01:29:30 Node.js

简体版:今天写的可能用处不大。读者慎重选择是否阅读它……?看来DPainMakingWheel系列的手笔没有第三方依赖LightweightNode-server,哇,一大堆形容词,看需求。产品说看页面怎么写,他不想动或者你不想看他。我认为主要是因为后者?那么问题来了,能不能让产品远离10米远呢?让他再看看页面,肯定可以,废话少说,直接开始写。Node知识点fshttpos从启动一个基本的Node服务开始,http模块参考文档http.createServer(function(request,response){//发送HTTPheader//HTTPstatusvalue:200:OK//Contenttype:text/plainresponse.writeHead(200,{'Content-Type':'text/plain'});//发送响应数据"HelloWorld"response.end('HelloWorld\n');}).listen(8888);//这样就启动了最基本的node服务,浏览器访问http://127.0.0.1:8888可以看到HelloWorld。那么万里长征第一步的踮脚动作就完成了,接下来就是如何实现打开我们自己的html页面了。如果要打开html页面,就必须访问文件,所以就得用到fs模块。下面的代码可以实现对脚本同目录下html文件的深度遍历。遍历页面需要的文件,fs模块参考文档functiongeFileList(path){varfilesList=[];读取文件(路径,文件列表);returnfilesList;}//获取文件类型functiongetType(filename){varindex=filename.lastIndexOf(".");if(index!=-1){vartype=filename.substring(index+1,filename.length);返回类型;}}//遍历读取文件functionreadFile(path,filesList){files=fs.readdirSync(path);//需要使用同步读取files.forEach(walk);functionwalk(file){states=fs.statSync(path+'/'+file);如果(states.isDirectory()){readFile(path+'/'+file,filesList);}else{varobj=newObject();obj.size=states.size;obj.name=file;//文件名obj.type=getType(file)filesList.push(obj);}}}//统计各种文件的个数functioncountFileByType(obj){varkeyContainer={};obj.forEach(item=>{keyContainer[item.type]=keyContainer[item.type]||[];keyContainer[item.type].push(item);});returnkeyContainer}module.exports.geFileList=geFileListmodule.exports.countFile=countFileByTypemodule.exports.getType=getType//方法模块化了,更容易理清文件读取操作的思路,emmmmmmm,但是写的不行十分优雅。它需要改进。可以启动Node服务,可以遍历文件。至此,基础设施建设已经完成。接下来,我们需要开启一个不需要看商品的服务。启动局域网服务,我们再把获取ip地址的方法分开来。需要用到的Node知识点是os模块。os模块的参考文档是constos=require('os');constgetlocalIp=()=>{varinterfaces=os.networkInterfaces();varipArr=[]for(vardevNameininterfaces){variface=interfaces[devName];对于(vari=0;i{varinterfaces=os.networkInterfaces().WLANvarWlanIp=''for(letipofinterfaces){if(ip.family=='IPv4'){WlanIp=ip.address}}returnWlanIp}module.exports.getlocalIp=getlocalIpmodule.exports.getWlanIp=getWlanIp//为什么要在这里预留两种ip地址,因为有时候我们也需要开通非局域网ip服务,multi-functionbonus写到这里突然想到了一个问题,我做这个功能还有一个很重要的目的就是解决http-server默认开启8080端口的缺陷,因为8080端口很有可能被占用,想到开启的时候不妨随便分配一个8###服务端口,这样端口被占用的可能性很小,可以实现一个随机数?下面我们来看一下实现功能的步骤。读取某个目录下的html文件,获取局域网IP地址/本机IP地址。自动打开随机端口进行浏览。转换器,集成核心步骤模块后生成索引文件链接importconsthttp=require('http');constfs=require('fs');constip=require('../lib/get-ip')constF=require('../lib/get-file')constroot=process.cwd();//当前目录constport=Math.floor(Math.random()*1000)+8000;varlocalIP=Ip.getlocalIp()varwlanIp=Ip.getWlanIp()||localIP[0]主要方法函数setHttpServer(){awaitsetConsoleInfo();awaitfs.exists('index.html',function(exists){if(!exists){openDefaultBrowser(`http://`+wlanIp+':'+port)}else{openDefaultBrowser(`http://`+wlanIp+':'+port+'/index.html')}})}启用服务并调试server=http.createServer(function(req,res){if(req.url==='/favicon.ico'){//console.log('\033[42;30mDONE\033[40;32m19987ms\033[0m')编译成功}else{varurl=req.url;varfile=root+url;fs.readFile(文件,函数(错误,数据){if(err){res.writeHeader(404,{'content-type':'text/html;charset="utf-8"'});if(!F.countFile(F.geFileList(root)).html){res.write('

404页面

当前目录没有html文件

')}else{letfileList=fs.readdirSync(`${file}`);for(letfoffileList){lettype=F.getType(f)if(type=='html'){res.write('
'+`${f}`+'\n')}}}res.end();}else{varsurl='.'+url;vartype=surl.substr(surl.lastIndexOf(".")+1,surl.length)res.writeHeader(200,{'content-type':"text/"+type+';'+'charset="utf-8"'});res.write(数据);重发();}})}}).listen(端口);控制台显示服务地址functionsetConsoleInfo(){letinfo='默认服务已在浏览器打开!'console.log('\033[42;30mDONE\033[;32m'+info+'\033[0m')for(letdevoflocalIP){console.log(`${dev}`+':'+port)}}自动打开浏览器函数openDefaultBrowser(url){varexec=require('child_process').exec;switch(process.platform){case"darwin":exec('open'+url);休息;case"win32":exec('开始'+url);休息;默认值:exec('xdg-open',[url]);}}至此,一个简单的没有第三方依赖的轻量级Node服务就建立起来了,过程有点粗糙,没有详细说明如何使用module方法,因为使用的方法比较简单。当然这个小插件还是有一定缺陷的,扩展性略低,只能满足简单的需求。有很大的改进空间,希望路过的小伙伴多多提出更好的建议。?[青铜玩家的真诚面孔]欢迎使用npm安装试用npmiset-node-serverset-server/ssgit通讯地址:vannvan/set-node-server