65 # 实现 http-server 里的 gzip 压缩

用 zlib 来实现 gzip 压缩

服务端优化都是:压缩 + 缓存

前端可以通过 webpack 插件进行压缩
gzip 根据替换来实现的,重复率越高,压缩后的结果越小

const zlib = require("zlib");
const fs = require("fs");
const path = require("path");

方式一:读取文件压缩,如果文件大的话都读取到内存中,耗内存

zlib.gzip(fs.readFileSync(path.resolve(__dirname, "./65/1.txt")), (err, data) => {fs.writeFileSync(path.resolve(__dirname, "./65/2.txt.gz"), data);
});

方式二:用转化流(可读可写)的方式,服务端的文件 => 压缩 => 客户端

fs.createReadStream(path.resolve(__dirname, "./65/1.txt")).pipe(zlib.createGzip()).pipe(fs.createWriteStream(path.resolve(__dirname, "./65/2.txt.gz")));

新建 1.txt 文件用来测试压缩,里面写的都是1,大概有个 10k 的样子,两种方式执行之后都会生成压缩文件 2.txt.gz,如下

在这里插入图片描述

代码实现 http-server 里的 gzip 压缩

下面实现 http-server 里的 gzip 压缩

实现思路就是根据请求头 header [accept-encoding] 里是否包含 gzip 来判断浏览器是否支持 gzip 压缩,如果支持就创建转化流处理。

在上一节的 server.js 里面添加代码如下

// 核心模块
const http = require("http");
const path = require("path");
const url = require("url");
const fs = require("fs").promises;
const { createReadStream, createWriteStream, readFileSync } = require("fs");// 第三方模块
const ejs = require("ejs"); // 服务端读取目录进行渲染
const mime = require("mime");
const chalk = require("chalk");
const debug = require("debug")("server");
// 根据环境变量来进行打印 process.env.EDBUG
debug("hello kaimo-http-server");// 同步读取模板
const template = readFileSync(path.resolve(__dirname, "template.ejs"), "utf-8");class Server {constructor(config) {this.host = config.host;this.port = config.port;this.directory = config.directory;this.template = template;}async handleRequest(req, res) {let { pathname } = url.parse(req.url);// 需要对 pathname 进行一次转义,避免访问中文名称文件找不到问题console.log(pathname);pathname = decodeURIComponent(pathname);console.log(pathname);// 通过路径找到这个文件返回let filePath = path.join(this.directory, pathname);console.log(filePath);try {// 用流读取文件let statObj = await fs.stat(filePath);// 判断是否是文件if (statObj.isFile()) {this.sendFile(req, res, filePath, statObj);} else {// 文件夹的话就先尝试找找 index.htmllet concatFilePath = path.join(filePath, "index.html");try {let statObj = await fs.stat(concatFilePath);this.sendFile(req, res, concatFilePath, statObj);} catch (e) {// index.html 不存在就列出目录this.showList(req, res, filePath, statObj, pathname);}}} catch (e) {this.sendError(req, res, e);}}// 列出目录async showList(req, res, filePath, statObj, pathname) {// 读取目录包含的信息let dirs = await fs.readdir(filePath);console.log(dirs, "-------------dirs----------");try {let parseObj = dirs.map((item) => ({dir: item,href: path.join(pathname, item) // url路径拼接自己的路径}));// 渲染列表:这里采用异步渲染let templateStr = await ejs.render(this.template, { dirs: parseObj }, { async: true });console.log(templateStr, "-------------templateStr----------");res.setHeader("Content-type", "text/html;charset=utf-8");res.end(templateStr);} catch (e) {this.sendError(req, res, e);}}gzip(req, res, filePath, statObj) {if (req.headers["accept-encoding"] && req.headers["accept-encoding"].includes("gzip")) {// 给响应头添加内容编码类型头,告诉浏览器内容是什么编码类型res.setHeader("Content-Encoding", "gzip");// 创建转化流return require("zlib").createGzip();} else {return false;}}// 读取文件返回sendFile(req, res, filePath, statObj) {// 设置类型res.setHeader("Content-type", mime.getType(filePath) + ";charset=utf-8");// 读取文件进行响应// 先判断浏览器是否支持 gzip 压缩let gzip = this.gzip(req, res, filePath, statObj);if (gzip) {createReadStream(filePath).pipe(gzip).pipe(res);} else {createReadStream(filePath).pipe(res);}}// 专门处理错误信息sendError(req, res, e) {debug(e);res.statusCode = 404;res.end("Not Found");}start() {const server = http.createServer(this.handleRequest.bind(this));server.listen(this.port, this.host, () => {console.log(chalk.yellow(`Starting up kaimo-http-server, serving ./${this.directory.split("\\").pop()}\r\n`));console.log(chalk.green(`       http://${this.host}:${this.port}`));});}
}module.exports = Server;

我们启动服务,去访问 http://localhost:3000/1.txt

kaimo-http-server

跟没有压缩的对比如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/82557.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打开的idea项目maven不生效

方法一:CtrlshiftA(或者help---->find action), 输入maven, 点击add maven projects,选择本项目中的pom.xml配置文件,等待加载........ 方法二:view->tools windows->mave…

条条大路通罗马系列—— 使用 Hiredis-cluster 连接 Amazon ElastiCache for Redis 集群

前言 Amazon ElastiCache for Redis 是速度超快的内存数据存储,能够提供亚毫秒级延迟来支持 实时应用程序。适用于 Redis 的 ElastiCache 基于开源 Redis 构建,可与 Redis API 兼容,能够与 Redis 客户端配合工作,并使用开放的 Re…

数组相关练习

数组练习 将数组转化成字符串数组拷贝求数组元素的平均值查找数组中指定元素(顺序查找)二分查找冒泡排序数组逆序 将数组转化成字符串 import java.util.Arrays;public class Text1 {public static void main(String[] args) {int[] arr {5, 6, 4, 2};System.out.println(Arr…

Android Framework解析——WMS原理

作者:bobby_developer 1. WMS原理:WMS角色与实例化过程 window:它是一个抽象类,具体实现类为 PhoneWindow ,它对 View 进行管理。Window是View的容器,View是Window的具体表现内容; windowManager:是一个接…

大学生口才培训需求分析

标题:大学生口才培训需求分析 摘要: 本论文旨在分析大学生口才培训的需求,通过对大学生口才培训的重要性、现状和挑战进行研究,并结合相关理论和实践经验,提出相应的培训需求和解决方案。通过本论文的研究&#xff0c…

js手写贪吃蛇游戏

前端手写贪吃蛇游戏 贪吃蛇游戏 场景 使用了js 和 html /css 就可以完成 一个贪吃蛇小游戏 技术分析 主要用到的几个技术点: clientWidth :元素的宽度,包含内边距clientHeight :元素的高度,包含内边距setInterval&am…

(八)穿越多媒体奇境:探索Streamlit的图像、音频与视频魔法

文章目录 1 前言2 st.image:嵌入图像内容2.1 图像展示与描述2.2 调整图像尺寸2.3 使用本地文件或URL 3 st.audio:嵌入音频内容3.1 播放音频文件3.2 生成音频数据播放 4 st.video:嵌入视频内容4.1 播放视频文件4.2 嵌入在线视频 5 结语&#x…

kubernetes中最小组件——Pod

目录 一、Pod简介 二、Pod的使用方式 三、Pause——Pod中底层基础容器 四、为什么kubernetes这样设计Pod 五、Pod的分类 1.自主式Pod 2.控制器管理的Pod 3.静态Pod 六、Pod容器的分类 1. 基础容器(infrastructure container) 2. 初始化容器&am…

Git与Github常用方法

目录 1. Github基本使用方法2. Git使用方法3. git、VS code、Github联合使用方法4. Git配置Github远程仓库SSH密钥5 常见问题 1. Github基本使用方法 仓库(Repository):Github上用来存放代码的空间,包含代码、文档和其他文件。提…

万应低代码受邀参加上海电信“大干一场 科创沙龙”活动

7月28日,由上海市宝山区大场镇政府指导、中国电信上海北区局主办的“大干一场 科创沙龙”系列第九期沙龙活动顺利举办。大场镇“数字化转型”领导小组办公室(以下简称“数字办”)邀请了来自镇域内外的数十家科创服务企业。万应低代码作为天翼…

flask-----蓝图

1.引入蓝图 flask都写在一个文件中,项目这样肯定不行,会导致循环导入的问题,分目录,分包,使用蓝图划分目录。 2.使用蓝图 步骤如下: -1 实例化得到一个蓝图对象-order_blueBlueprint(order,__name__,tem…

医疗行业如何防范弱口令攻击?这份弱口令治理方案请收好

随着5G、云计算、物联网等新兴技术与传统医疗系统的不断深化融合,我国医疗信息化程度越来越高,逐步向数字化、智慧化医疗演进,蓬勃发展的信息化也使医疗行业面临的安全风险逐渐增多。数据泄露、勒索病毒等问题频发,加之《等保》、…

JavaScript |(四)正则表达式 | 尚硅谷JavaScript基础实战

学习来源:尚硅谷JavaScript基础&实战丨JS入门到精通全套完整版 系列笔记: JavaScript |(一)JavaScript简介及基本语法JavaScript |(二)JavaScript自定义对象及函数JavaScript |(三&#xff…

hcip——期中小试

要求: 1、该拓扑为公司网络,其中包括公司总部、公司分部以及公司骨干网,不包含运营商公网部分。 2 、设备名称均使用拓扑上名称改名,并且区分大小写。 3 、整张拓扑均使用私网地址进行配置。 4 、整张网络中,运行 O…

21、springboot的宽松绑定及属性处理类的构造注入

springboot的宽松绑定及属性处理类的构造注入 ★ 如何使用属性处理类所读取的属性 属性处理类最终变成了Spring容器中的一个Bean组件,因此接下来Spring即可将该Bean组件注入任意其他组件。 这种做法的好处是:可以将大量的配置信息封装一个对象——所以…

Spring boot 集成 Skywalking 配置 || Skywalking 打不开【已解决】

一、Skywalking官网 Apache SkyWalking 1.下载Skywalking APM (如果下载最新的,双击打开闪退,选老点的版本) 2. 下载 Skywalking Agents 如果下载太慢,建议复制下载链接,然后用下载器下载,比…

时间复杂度空间复杂度相关练习题

1.消失的数字 【题目】:题目链接 思路1:排序——》qsort快排——》时间复杂度O(n*log2n) 不符合要求 思路2:(0123...n)-(a[0]a[1][2]...a[n-2]) ——》 时间复杂度O(N)空间复杂度…

软件验收测试包括几种类型?验收测试报告有什么好处?

在软件开发中,验收测试是软件项目在开发完成后进行的最后一项测试工作。它是确认软件是否满足预期要求,并准备将软件交付用户的核心环节,它可以确保软件的质量和功能符合用户的需求和期望。 一、软件验收测试的类型 软件验收测试可以分为多…

Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis tbms

​ 功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查…