UNPKG

static-server-function

Version:

179 lines (167 loc) 7.94 kB
//1.引入http模块 const http = require('http'); //引入url模块 const urlTool = require('url') //引入 path模块 const path = require('path'); //引入fs模块 const fs = require('fs') //引入ejs(模块化工具) const ejs = require('ejs'); //引入 mimes 对象(响应头) const mimes = require('./mimes/mimes') //引入zlib模块 (压缩) const zlib = require('zlib') //引入 etag 工具 const etag = require('etag') //引入配置文件对象 const config = require('./config/config') //引入 open.js const open = require('./libs/open') class H51227{ constructor(options){ Object.assign(config, options); console.log(config); } run(){ //2.创建服务 const server = http.createServer((request,response) =>{ //获取请求的路径 let url = urlTool.parse(request.url).pathname; //拼接文件的路径 // resolve方法第二个参数如果是一个绝对路径,则返回这个绝对路径 // let filePath =path.resolve(config.root + url) let filePath = config.root + url; //检测路径对应资源的类型 fs.stat(filePath,(err,stats)=> { if(err){ response.statusCode = 404; response.end('<h1>404 Not Found</h1>') return; } //检测是否为文件夹 if(stats.isDirectory()){ //读取文件夹中的内容 fs.readdir(filePath,(err,data)=>{ if(err){ response.statusCode = 500; response.end('<h1>500 Internal Error</h1>') return; } //设置一下响应头 response.setHeader('content-type','text/html;charset/utf-8'); let templateFilePath = path.resolve(__dirname,'views/directory.html') ejs.renderFile(templateFilePath,{data:data,url:url},(err,data)=>{ if (err){ response.statusCode = 500; response.end('<h1>500 Internal Error</h1>') return ; } response.end(data) }) }) }else{ //判断是否开启协商缓存 if(config.cache.xieCache) { //检测客户端请求的 if-none-match if-modified-since let requestEtag = request.headers['if-none-match'] let requestLastModified = request.headers['if-modified-since'] //重新计算当前文件的 etag 值 let currentFileEtag = etag(stats); let currentFileModifiedTime = stats.mtime.toUTCString() // //判断 if (requestEtag === currentFileEtag || requestLastModified === currentFileModifiedTime) { //响应304 response.statusCode = 304; response.end() return; } } //如果是文件的话 //获取文件的后缀 url /index.html const suffix = url.split('.').pop(); if(mimes[suffix] === undefined){ //text/plain也是一种类型 浏览器会原文输出内容 response.setHeader('content-type','text/plain;charset=utf-8'); }else{ response.setHeader('content-type',mimes[suffix]); } //设置强制缓存 判断 if(config.cache.qiangCache){ response.setHeader('cache-control','max-age='+config.cache.cacheTime) } // response.setHeader('cache-control','max-age=300') //设置协商缓存 etag let etagValue = etag(stats); response.setHeader('Etag',etagValue); response.setHeader('last-modified',stats.mtime.toUTCString()) // 读取文件内容 fs.readFile(filePath,(err,data)=>{ if(err){ response.statusCode = 500; response.end('<h1>Interval server Error</h1>') return; } //判断支持的压缩方式 let encoding = request.headers['accept-encoding'];//undefined //判断如果没有指定 encoding if(encoding === undefined){ response.end(data) ; return ; } // 判读encoding中是否有gzip if (encoding.indexOf('gzip') !== -1) { //设置响应头 response.setHeader('content-encoding', 'gzip'); //对响应头的数据进行压缩 zlib.gzip(data,(err,result)=>{ if(err){ //如果出错 response.statusCode = 500; response.end('<h1>Interval server Error</h1>') return; } response.end(result) }) } //判读encoding中是否有 deflate br else if(encoding.indexOf('deflate')!==-1){ //设置响应头 response.setHeader('context-encoding','deflate') //对响应头的数据进行压缩 zlib.deflate(data,(err,result)=>{ if(err){ response.statusCode = 500; response.end('<h1>Interval server Error</h1>') return; } response.end(result) }) } //判读encoding中是否有 br else if(encoding.indexOf('br')!==-1){ //设置响应头 response.setHeader('context-encoding','br') //对响应头的数据进行压缩 zlib.brotliCompress(data,(err,result)=>{ if(err){ response.statusCode = 500; response.end('<h1>Interval server Error</h1>') return; } response.end(result) }) } //传内容 }) } }) }) //3.启动服务,监听端口 server.listen(config.port,()=>{ console.log(`服务已经启动,端口${config.port}监听中`) open(`http://127.0.0.1:${config.port}`) }) } } module.exports = H51227;