const log = (...value) => console.log(...value)
const url = require('url')
const http = require('http')
const fs = require('fs')
const path = require('path')
// 获取当前目录
let root = path.resolve()
let isFindFile = false
let filename = 'a.html'
// 读文件
let readFiles = function (obj) {
let {res, fs, filepath} = obj
/**
* res.writeHead(statusCode, headers): 发送一个响应头给请求 该方法在响应中
只能被调用一次 且必须在 response.end() 被调用之前调用
statusCode: 状态码是一个3个数字的HTTP状态代码 如 404
headers: 响应头
*/
res.writeHead(200)
// 读取文件并写入 res对象 直接用pipe()方法就实现了自动读取文件内容并输出到HTTP响应
fs.createReadStream(filepath).pipe(res)
}
let closeResponent = function (res) {
res.writeHead(404)
res.end('404 Not Found')
}
// 比较文件 获取 a.html
let readStream = function (value) {
let {res, file, v, filepath} = value
let objFile = fs.statSync(file)
if ( objFile.isFile() && v === filename) {
// createReadStream: 写入流是同步的 正在写的文件没完成 就不会往下执行
fs.createReadStream(path.join(filepath, v)).pipe(res)
isFindFile = true
}
if ( objFile.isFile() && v === 'newFile.html') {
fs.createReadStream(path.join(filepath, v)).pipe(res)
isFindFile = true
}
}
// 读文件目录
let readdirFile = function (value) {
let {res, filepath} = value
let exit = false
/**
* readdir(err, options, files): 读取一个目录的内容
files: 读取的文件数组名
*/
fs.readdir(filepath, (err, files) => {
files && files.forEach(v => {
let file = path.join(filepath, v)
// fs.createReadStream 没读完 进程完全阻塞
readStream({file, res, v, filepath} )
})
// 如果没找到文件 弹出404
if (!isFindFile) {
closeResponent(res)
}
})
}
/**
* createServer(req, res): 创建服务器
req: 封装了HTTP请求信息
res: 封装了HTTP响应信息 操作response对象的方法 可以把HTTP响应返回给浏览器
*/
let server = http.createServer((req, res) => {
/**
* req.url: 请求链接
* url.parse(请求地址, true): 返回一个对象
* 获取请求文件名 类似 /css/index.html?name=xl
*/
pathname = url.parse(req.url, true).pathname
// 获取文件绝对路径 类似 /Library/WebServer/Documents/index.html
let filepath = path.join(root, pathname)
// fs.stat 获取文件信息
fs.stat(filepath, (err, stats) => {
// stats.isFile(): 是否是文件
if (!err && stats.isFile()) {
readFiles({res, fs, filepath})
} else {
readdirFile({filepath, res})
}
})
})
server.listen(8888)