1.知识必备
(1)当服务器响应不同文件类型时,需要设置响应报文头,让浏览器选择相应的编码数据。
常用对照表HTTP Mime-type:
https://tool.oschina.net/commons
思路:根据访问的路径来提取后缀名,再根据后缀名设置相应的 Content-Type
(2)请求路径不存在时设置返回的状态码
res.statusCode = 404 res.statusMessage = 'Not found'
(3)需要用到path模块和fs模块拼接路径即读取文件
2.模拟Apache服务器(一)
共封装了4个方法;
getFileType(url):根据url获取文件类型
setContentType(res,fileType):根据文件类型设置Mime-type
renderFile(res,url):根据路径读取相应的文件并返回给客户端
troubleShooting(res,url,fileType):错误处理函数
源码:
// 引入http模块 const http = require("http"); //引入fs模块 const fs = require('fs'); //引入path模块 (拼接路径) const path = require('path'); // 创建一个服务器 var server = http.createServer((req,res)=>{ //获取文件类型 var fileType = getFileType(req.url) if(!fileType) fileType = "html" //设置ContentType setContentType(res,fileType) //读取文件并返回 renderFile(res,req.url) }); // 监听接口,需运行此文件,浏览器才能正常访问 "127.0.0.1" server.listen(80,"127.0.0.1",function(err){ if(err){ throw err; } console.log('Server running at http://127.0.0.1:80/'); }); //根据url获取后缀名 function getFileType(url){ //定义文件类型 var fileType = "" //获取 "." 在url中的下标位置 var index = url.lastIndexOf('.') if(index>=0){ // xxx.jpg => jpg fileType = url.substring(index+1) } return fileType } //根据后缀名设置响应头 function setContentType(res,fileType){ var contrast = { html:"text/html;charset=utf-8", css:"text/css", txt:"text/plain;charset=utf-8", jpg:"image/jpeg", png:"image/png", jpeg:"image/jpeg", svg:"text/xml", gif:"image/gif", mp3:"audio/mp3", mp4:"video/mpeg4", pdf:"application/pdf" } //设置默认的ContentType为text/html;charset=utf-8 var ContentType = "text/html;charset=utf-8" //如果文件类型为空,则默认设置为html格式 if(!fileType) fileType = "html" //匹配文件类型 Object.keys(contrast).forEach((key) => { if(key === fileType){ ContentType = contrast[key] //跳出遍历 return false } }) //设置响应头 res.setHeader("Content-Type",ContentType) } //封装读取文件的函数 (依赖path和fs模块) function renderFile(res,url){ //如果访问根目录 if(url=='/'){ url = '/index.html'; } //设置静态文件根目录 var root = "www" //拼接路径 var filePath = path.join(__dirname,root,url) //读取文件 fs.readFile(filePath,function(err,data){ if(err){ //处理异常 troubleShooting(res,url,fileType) }else{ //返回文件内容 res.end(data) } }) } //封装处理错误的函数 function troubleShooting(res,url,fileType){ console.log(url+"文件不存在") //设置返回的状态码 res.statusCode = 404 res.statusMessage = 'Not found' //根据文件类型返回不同的数据 if(fileType){ res.end("") }else{ //返回404页面 res.end("页面不存在") } }
3.模拟Apache服务器(二)
(1)文件类型多种多样,每样都要手动设置Mime-Type费时费力,可以使用第三方模块来完成
这个模块就是 mime
安装mime模块
npm i mime
mime的作用就是根据url的后缀,返回对应的Content-Type
const mime = require("mime") console.log(mime.getType("xxx.css")) // text/css console.log(mime.getType("/")) // null
完整代码:
const http = require('http'); const path = require('path'); const fs = require('fs'); const mime = require('mime'); var server = http.createServer((req,res)=>{ var contentType = mime.getType(req.url); res.setHeader('Content-Type',contentType); returnFile(req.url,res); }) //根据url和文件类型返回对应的文件 function returnFile(url,res){ //如果访问根目录 if(url=='/'){ url = '/index.html'; } var result = path.join(__dirname,'www',url); fs.readFile(result,function(err,data){ if(err){ res.end('页面不存在'); } res.end(data); }) } server.listen(80,"127.0.0.1",function(err){ if(err){ throw err; } console.log('Server running at http://127.0.0.1:80/'); })