,因为我想在项目中做一个mock数据服务器。目前作为项目中的模拟数据服务器,还有一些问题需要处理。所以先贴出目前只有《Node.js搭建本地文件服务器》的源码。效果访问http://localhost:3000/,显示mock/mockapi/下的所有目录和文件;访问http://localhost:3000/getUsersInfo.json显示mock/mockapi/getUsersInfo.json文件数据。源代码//mock/index.jsconsthttp=require('http');constprocessRequest=require('./server');常量端口=3000;consthttpServer=http.createServer((req,res)=>{processRequest(req,res)})httpServer.listen(port,()=>{console.log(`app在端口运行:${port}`);});//mock/server.jsconstfs=require('fs')consturl=require('url')constpath=require('path')constmime=require('./mime')constheaders={'Access-Control-Allow-Origin':'*',//允许跨域'Content-Type':'text/plain'}constprocessRequest=(request,response)=>{letpathName=url.parse(request.url).pathname//防止中文乱码pathName=decodeURI(pathName)//获取资源文件的绝对路径letfilePath=path.resolve(__dirname+'/mockapi/'+pathName)//文件扩展名letext=path.extname(pathName)ext=ext?ext.slice(1):'unknown'//所有未知类型都使用“text/plain”类型headers['Content-Type']=mime[ext]||"'text/plain'"//301重定向if(!pathName.endsWith('/')&&path.extname(pathName)===''){pathName+='/'varredirect='http://'+request.headers.host+pathNameresponse.writeHead(301,{location:redirect})response.end()}fs.stat(filePath,(err,stats)=>{//未找到文件if(err){headers['Content-Type']='text/html'response.writeHead(404,headers)response.end("
404NotFound
")}//文件if(!err&&stats.isFile()){fs.readFile(filePath,(err,data)=>{if(err){response.writeHead(500,headers)response.end('
500ServerError
')}response.writeHead(200,headers);response.end(data)})}//目录if(!err&&stats.isDirectory()){varhtml='
'fs.readdir(filePath,(err,files)=>{if(err){html+=`
读取路径失败!
`response.writeHead(404,headers)response.end(html)}else{headers['Content-Type']='text/html'response.writeHead(200,headers)for(varfileoffiles){if(file==='index.html'){response.end(file)break}html+=`
`}response.end(html)}})}})}module.exports=processRequest//mock/mime.jsmodule.exports={"css":"text/css","gif":"image/gif","html":"text/html","ico":"image/x-icon","jpeg":"image/jpeg","jpg":"image/jpeg","js":"text/javascript","json":"application/json","pdf":"application/pdf","png":"image/png","svg":"image/svg+xml","swf":"application/x-shockwave-flash","tiff":"image/tiff","txt":"text/plain","wav":"audio/x-wav","wma":"audio/x-ms-wma","wmv":"视频/x-ms-wmv","xml":"text/xml"};讲解知识点http-HTTPfs-文件系统路径-路径url-创建服务器的URLhttp.createServer([options][,requestListener])返回一个新的http.Server实例;http.Server类继承fromnet.Server;net.Server类用于创建TCP或IPCserverserver.listen(options[,callback])开启HTTP服务器监听连接,mock/server.js文件封装了response和请求进入匿名函数,传递到http.createServer()。//mock/index.jsconsthttp=require('http');constprocessRequest=require('./server');常量端口=3000;consthttpServer=http.createServer((req,res)=>{processRequest(req,res)})httpServer.listen(port,()=>{console.log(`app在端口运行:${port}`);})获取请求资源的路径//mock/server.jsconsturl=require('url')constpath=require('path')constprocessRequest=(request,response)=>{letpathName=url.parse(request.url).pathname//防止中文乱码pathName=decodeURI(pathName)//获取资源文件的绝对路径letfilePath=path.resolve(__dirname+'/mockapi/'+pathName)}url.parse()请求http://localhost:3000/api/users.json地址,其中,request.url为/api/users.json;请求http://localhost:3000/api/users.json?a=1地址,其中request.url为/api/users.json?a=1。所以这里需要用到,url模块解析url。url模块提供了一些用于URL处理和解析的实用函数。url.parse()方法解析URL字符串并返回URL对象。在下图中,URLhttp://user:pass@sub.host.com:8080/p/a/t/h?query=string#hash是url.parse()返回的对象的一个??属性。在这里,我们可以使用pathName来找到文件相对于mock/mockapi/的路径。path.resolve()有了pathName,现在我们需要获取资源文件的绝对路径filePath,方便后面的文件查找和文件读取。路径模块提供了用于处理文件和目录路径的实用函数。path.resolve([...paths])方法将路径或路径片段序列解析为绝对路径。示例:path.resolve('/foo/bar','./baz');//返回'/foo/bar/baz'path.resolve('/foo/bar','/tmp/file/');//Return'/tmp/file'path.resolve('wwwroot','static_files/png/','../gif/image.gif');//如果当前工作目录是/home/myself/node,//returns'/home/myself/node/wwwroot/static_files/gif/image.gif'redirection如果它是一个访问目录文件并且不以'/'结尾,在这里做一些事情并重定向到末尾访问路径在地址中添加'/'。//301重定向if(!pathName.endsWith('/')&&path.extname(pathName)===''){pathName+='/'varredirect='http://'+request.headers.host+pathNameresponse.writeHead(301,{location:redirect})response.end()}在响应头后返回数据时,需要使用response.writeHead(statusCode[,statusMessage][,headers])方法向请求发送响应标头。状态码是三位数的HTTP状态,比如404。最后一个参数headers是响应头。第二个参数statusMessage是一个可选的状态描述。这里需要设置响应头的Access-Control-Allow-Origin和Content-Type。Content-Type,内容类型,一般是指存在于网页中的Content-Type,用于定义网络文件的类型和网页的编码,并决定浏览器将以何种形式和编码读取这个文件。Access-Control-Allow-Origin:
指定是否允许与给定的org共享响应的资源;*用作通配符,允许所有域都有访问该资源的权限。constheaders={'Access-Control-Allow-Origin':'*',//允许跨域'Content-Type':'text/plain'}constprocessRequest=(request,response)=>{letpathName=url.parse(request.url).pathname//防止中文乱码pathName=decodeURI(pathName)//文件扩展名letext=path.extname(pathName)ext=ext?ext.slice(1):'unknown'//未知类型总是使用“text/plain”类型headers['Content-Type']=mime[ext]||"'text/plain'"}读取文件fs模块提供了一些API,用于使用类似的标准POSIX函数与文件系统进行交互。fs.Stats对象提供有关文件的信息。可以从fs.stat()返回。stats.isDirectory()如果fs.Stats对象表示文件系统目录,则返回true。如果fs.Stats对象表示一个普通文件,stats.isFile()返回true。fs.readFile(path[,options],callback)异步读取文件的全部内容。fs.readdir(path[,options],callback)异步读取目录的内容fs.stat(filePath,(err,stats)=>{//找不到文件if(err){headers['Content-Type']='text/html'response.writeHead(404,headers)response.end("404NotFound
")}//fileif(!err&&stats.isFile()){fs.readFile(filePath,(err,data)=>{if(err){response.writeHead(500,headers)response.end('500服务器错误
')}response.writeHead(200,headers);response.end(data)})}//目录if(!err&&stats.isDirectory()){varhtml=''fs.readdir(filePath,(err,files)=>{if(err){html+=`读取路径失败!
`response.writeHead(404,headers)response.end(html)}else{headers['Content-Type']='text/html'response.writeHead(200,headers)for(varfileoffiles){if(file==='index.html'){response.end(file)break}html+=``}response.end(html)}})}})returndataresponse.end([data][,encoding][,callback])这个方法会通知服务器所有的响应头和响应主题已经发送完毕,必须为服务器认为完整的每个响应调用response.end()方法。如果指定data,则相当于在调用response.write(data,encoding)后调用response.end(callback)。如果指定了回调,则在响应流结束时调用它。response.writeHead(404,headers)response.end('500ServerError
')Node.js中文网