Node.js 模拟Apache服务器

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。
语法:mime.getType(urlStr)

const mime = require("mime")
console.log(mime.getType("xxx.css")) // text/css
console.log(mime.getType("/")) // null

完整代码:

//引入http模块(用于创建http服务)
const http = require('http');
//引入path模块 (用于拼接路径)
const path = require('path');
//引入fs模块 (用于读取文件)
const fs = require('fs');
//引入mime模块(用于设置mime-type)
const mime = require('mime');

//创建http服务对象
var server = http.createServer((req,res)=>{
    //根据url获取对应的mime-type
    var contentType = mime.getType(req.url);
    //设置Content-Type
    res.setHeader('Content-Type',contentType);
    //根据url读取对应的文件并返回给客户端
    returnFile(req.url,res);
})



//根据url返回对应的文件
function returnFile(url,res){
    //如果访问根目录就视为访问index.html
    if(url=='/'){
        url = '/index.html';
    }
    //设置静态资源目录
    var root = "www"
    //拼接路径
    var targetPath = path.join(__dirname,root,url);
    fs.readFile(targetPath,function(err,data){
        if(err){
            res.end('页面不存在');
        }
        res.end(data);
    })
}

//开启服务,监听80端口
server.listen(80,"127.0.0.1",function(err){
    if(err){
		throw err;
	}
	console.log('Server running at http://127.0.0.1:80/');
})

4.总结

(1)搭建服务器需要的模块有:

  • http:创建http服务
  • path:拼接路径
  • fs:读取文件
  • mime:设置mime-type

(2)搭建服务器的步骤为:

  • 引入相关模块
  • 创建http服务对象,设置路由,监听用户访问的路径
  • 根据url设置mime-type,保证客户端能正确解析数据
  • 读取要返回的文件并响应给客户端
  • 结束响应
posted @ 2019-10-11 12:50  ---空白---  阅读(378)  评论(0编辑  收藏  举报