http静态服务

实现一个http静态服务器要考虑以下几个方面:

  1. 能够准确识别目标访问路径
  2. 判断目标路径是文件夹还是文件,前者返回index.html,后者返回该文件
  3. 以pipe形式将目标文件输出,并指定Content-type
  4. 如果目标路径不存在,设置状态码为404,提示404 not found

path.resolve和path.join的区别

  1. 大多数情况下两者表现一致,都可用于路径解析,生成规范化路径
  2. 主要区别在于,resolve类似于cd命令,遇到 / 会解析为根路径,join则不会
  3. join是单纯的拼接,resolve会将路径解析为一个绝对路径

代码实现

const http = require('http')
const path = require('path')
const fs = require('fs')
const url = require('url')
const mime = require('mime')

http.createServer((req, res) => {
    try {
        //获取拼接后的请求路径
        let filePath = path.join(__dirname, url.parse(req.url).pathname)
        const stat = fs.statSync(filePath);
        // 判断目标路径是文件夹还是文件,
        if (stat.isDirectory(filePath)) {
            //文件存在则返回index.html 否则返回404
            filePath = path.join(filePath, 'index.html')
            if (fs.existsSync(filePath)) {
                //通过管道形式返回并指定响应头Content-type
                res.setHeader('Content-type', 'text/html;charset=utf-8')
                fs.createReadStream(filePath).pipe(res)
            }else{
                //返回404 not found 
                res.statusCode = 404
                res.setHeader('Content-type', 'text/plain;charset=utf-8')
                res.end('404 not found')
            }
        } else {
            if (fs.existsSync(filePath)) {
                //通过管道形式返回 并指定响应头Content-type
                //通过第三方包mime获取文件mime类型
                const mimeType = mime.getType(filePath)
                res.setHeader('Content-type', `${mimeType};charset=utf-8`)
                fs.createReadStream(filePath).pipe(res)
            }
        }
    } catch (err){

        console.log(err)
        //返回404 not found 
        res.statusCode = 404
        res.setHeader('Content-type', 'text/plain;charset=utf-8')
        res.end('404 not found')
    }
}).listen(3000, () => {
    console.log('run server 3000 ')
})


http静态服务(类版本)


const http = require('http')
const path = require('path')
const fs = require('fs')
const url = require('url')
const mime = require('mime')
class HttpServer {

    handleRequest(req, res) {

        try {
            //获取拼接后的请求路径
            let filePath = path.join(__dirname, url.parse(req.url).pathname)
            const stat = fs.statSync(filePath);
            this.sendFile(stat, filePath, req, res)
        } catch(err) {
            console.log(err)
            this.sendError(res)
        }
    }

    start(...args) {
        http.createServer(this.handleRequest.bind(this)).listen(...args)
    }

    sendFile(stat, filePath, req, res) {
        // 判断目标路径是文件夹还是文件,
        if (stat.isDirectory(filePath)) {
            //文件存在则返回index.html 否则返回404
            filePath = path.join(filePath, 'index.html')
            if (fs.existsSync(filePath)) {
                //通过管道形式返回并指定响应头Content-type
                res.setHeader('Content-type', 'text/html;charset=utf-8')
                fs.createReadStream(filePath).pipe(res)
            }else{
                this.sendError(res)
            }
        } else {
            if (fs.existsSync(filePath)) {
                //通过管道形式返回 并指定响应头Content-type
                //通过第三方包mime获取文件mime类型
                const mimeType = mime.getType(filePath)
                res.setHeader('Content-type', `${mimeType};charset=utf-8`)
                fs.createReadStream(filePath).pipe(res)
            }
        }
    }

    sendError(res) {
        //返回404 not found 
        res.statusCode = 404
        res.setHeader('Content-type', 'text/plain;charset=utf-8')
        res.end('404 not found')
    }
}

new HttpServer().start(3000)


再会


情如风雪无常,

却是一动既殇。

感谢你这么好看还来阅读我的文章,

我是冷月心,下期再见。