http静态服务
1 回调方式
// 浏览器请求服务器的内容,进行回显
const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
// mime处理内容类型
const mime = require('mime');
const server = http.createServer((req, res) => {
// 解析浏览器请求的资源路径
const { pathname } = url.parse(req.url);
// 拼接路径,得到资源路径的绝对路径
let absPath = path.join(__dirname, pathname);
// 判断当前路径是文件还是目录,若是目录,则默认找该目录下的index.html文件;若是文件则直接读取该文件
fs.stat(absPath, (err, statObj) => {
if (err) {
res.statusCode = 404; //资源不存在
return res.end('Not Found');
}
if (statObj.isDirectory()) {
absPath = path.join(absPath, 'index.html');
}
fs.readFile(absPath, 'utf8', (err, data) => {
if (err) {
res.statusCode = 404; //资源不存在
return res.end('Not Found');
}
const type = mime.getType(absPath);
res.setHeader('Content-Type', type + ';charset=utf-8');
res.end(data);
});
});
});
server.listen(8888, () => {
console.log('server start at 8888');
})
2 通过类改写静态服务
const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs').promises;
const mime = require('mime');
// http支持可读流方式发送数据
let { createReadStream } = require('fs');
// 通过类改写静态服务
class Server {
async handleServer(req, res) {
const { pathname } = url.parse(req.url);
let absPath = path.join(__dirname, pathname);
try {
const statObj = await fs.stat(absPath);
if (statObj.isDirectory()) {
absPath = path.join(absPath, 'index.html');
}
// 发送读取的文件内容
this.sendFile(req, res, absPath);
} catch (e) {
// 处理错误
this.sendError(req, res);
}
}
start() {
let server = http.createServer(this.handleServer.bind(this));
server.listen(...arguments);
}
sendError(req, res) {
res.statusCode = 404;
res.end('Not Found');
}
sendFile(req, res, absPath) {
const type = mime.getType(absPath);
res.setHeader('Content-Type', type + ';charset=utf-8');
createReadStream(absPath).pipe(res);
}
}
let server = new Server();
server.start(8888, () => {
console.log('server start at 8888');
});
3 缓存
浏览器缓存方式有:
- 强制缓存
- 对比缓存(协商缓存)
const http = require('http');
const fs = require('fs').promises;
const path = require('path');
const url = require('url');
const mime = require('mime');
const { createReadStream } = require('fs');
http.createServer(async(req, res) => {
let { pathname } = url.parse(req.url);
let absPath = path.join(__dirname, pathname);
try {
const statObj = await fs.stat(absPath);
if (statObj.isDirectory()) {
// 如果是目录,默认加载目录下的index.html文件
absPath = path.join(absPath, 'index.html');
}
const type = mime.getType(absPath) || 'text/plain';
// 1.设置强制缓存,在有效时间内文件名未发生变化,需要的资源会从浏览器内存中加载
// res.setHeader('Expires', new Date(Date.now() + 60 * 1000).toGMTString());
// res.setHeader('Cache-control', 'max-age=60');
// 2.设置对比缓存
// no-cache 需要使用对比缓存验证数据,判断访问的文件是否修改,没有修改就告知浏览器从内存中加载数据,修改了就重新发送新内容
res.setHeader('Cache-control', 'no-cache');
const statObj2 = await fs.stat(absPath);
const ctime = statObj2.ctime.toGMTString();
res.setHeader('Last-Modified', ctime);
const since = req.headers['if-modified-since'];
if (ctime === since) {
// 文件没有修改
res.statusCode = 304;
res.end();
return;
}
// 发送读取的数据
res.setHeader('Content-Type', type + ';charset=utf-8');
createReadStream(absPath).pipe(res);
} catch (e) {
res.statusCode = 404;
res.end('Not Found');
}
}).listen(8080, () => {
console.log('server start at 8080...');
});