ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Node.js 模拟Apache服务器

2019-10-11 13:03:29  阅读:261  来源: 互联网

标签:Node err url res fileType js var mime 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

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/');
})

标签:Node,err,url,res,fileType,js,var,mime,Apache
来源: https://www.cnblogs.com/OrochiZ-/p/11653527.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有