- Note
- let 块级作用域
- 不存在变量提升
- let不允许在相同作用域内重复声明一个变量
- const 只允许声明常量,即具有不可变性
- 箭头函数
- ES6中的class
- 可以直接定义class
- 构造函数constructor
- class的方法可以省略掉function关键字
- 使用类的方法用.访问
- Promise对象
- 异步编程,避免无限嵌套的回调函数
- 用法
- new Promsie(function(resolve,reject){})
- 默认的两个参数都是函数
- 只有在
async
函数内部,才可能用await
关键字直接解析Promise对象 then(resove_func)
使用then方法的宿主必须是个promise对象catch(reject_func)
- 原理
- 通过fs模块读取客户端请求的文件内容
- 通过http模块将内容发送给客户端
- mime模块获取文件类型
- 模块
- fs 文件操作(默认异步操作)
- http 服务器相关
- mime 用于处理Content-Type
- url 解析url字符串返回URL对象
源码
'use strict'
const http = require('http')
const fs = require('fs')
const url = require('url')
const mime = require('mime')
// ES6语法 创建并导出静态类
module.exports = class StaticServer {
/**
* 构造函数初始化
* @param {object} options 选项
*/
constructor(options) {
// http对象
this.currentServer = null
// 默认选项
this.options = {
port: 8080,
host: '127.0.0.1',
filePath: './public',
homePage: '/index.html'
}
// 选项合并
for (let key in options) {
this.options[key] = options[key]
}
}
/**
* 服务器启动函数
*/
run() {
// 实例绑定
let self = this
// 创建http服务
this.currentServer = http.createServer((req, res) => {
// 使用url模块解析url字符串
let tmpUrl = url.parse(req.url).pathname
// 自动指定首页
let reqUrl = tmpUrl === '/' ? self.options.homePage : tmpUrl
// 组装文件地址
let filePath = self.options.filePath + reqUrl
// 使用Promise
// 检测文件是否存在
// 可以使用then时要求前者返回的是一个promise对象
self.checkFilePromsie(filePath).then(() => {
// 文件存在尝试读取文件
return self.readFilePromise(filePath)
}).then((data) => {
// 读取成功则发送数据
self.sendData(res, data, reqUrl)
}).catch(() => {
//统一处理错误
self.catch404(res)
})
}).listen(this.options.port, () => {
console.log("listening " + this.options.port)
})
}
checkFilePromsie(path) {
// 抛出Promise对象
return new Promise((resolve, reject) => {
// 检测当前目录或文件是否存在,返回一个promise对象
// 内部使用resolve与reject函数
fs.access(path, fs.R_OK, (err) => {
if (err) {
reject(err)
} else {
resolve('sucess')
}
})
})
}
// 以promsie对象返回,读取文件内容
readFilePromise(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
// 关闭服务
close() {
this.currentServer.close(() => {
close.log('Server closed.')
})
}
// 捕获404错误
catch404(res) {
// 响应头
res.writeHead(404, {
'Content-Type': 'text/plain'
})
// 响应体
res.write('Error 404. Resource not found.')
// 结束行
res.end()
}
// 发送文件内容
sendData(res, data, url) {
res.writeHead(200, {
// 获取文件类型头,去掉最开始的那个/ 故从1开始截取
'Content-Type': mime.getType(url.substring(1))
})
res.write(data)
res.end()
}
}
'use strict'
const StaticServer = require('./StaticServer')
let server = new StaticServer()
server.run()
// server.close()