• HTTP 传输内容的压缩


    总结:

    内容编码:通过content-encoding来指定内容的压缩方式,通过content-length来指定文件大小,服务端会在缓冲指定大小的数据后才发送到浏览器,浏览器收到指定大小的数据后认为文件已接收完毕,之后用相应的压缩方式对内容进行解压。

    传输编码:上述方式中服务器等指定大小的资源缓冲好才发给浏览器,造成浏览器等待时间长,会影响用户体验。可通过transfer-encoding:chunked来改变这一行为:服务器会将文件内容分块传输给浏览器而不用等所有缓冲完,最后一块大小为0,指示浏览器只要收到数据就进行处理展示而不用等所有收到。

    content-encoding和transfer-encoding通常结合使用。详情可参阅:https://imququ.com/post/transfer-encoding-header-in-http.html

    一、HTTP压缩和内容编码的区别

    HTTP压缩,在HTTP协议中,其实是内容编码的一种。

    在http协议中,可以对内容(也就是body部分)进行编码, 可以采用gzip这样的编码。 从而达到压缩的目的。 也可以使用其他的编码把内容搅乱或加密,以此来防止未授权的第三方看到文档的内容。

    所以我们说HTTP压缩,其实就是HTTP内容编码的一种。 所以大家不要把HTTP压缩和HTTP内容编码两个概念混淆了。

    二、HTTP压缩

    HTTP压缩是指: Web服务器和浏览器之间压缩传输的”文本内容“的方法。 HTTP采用通用的压缩算法,比如gzip来压缩html,javascript, CSS文件。 能大大减少网络传输的数据量,提高了用户显示网页的速度。当然,同时会增加一点点服务器的开销。 本文从HTTP协议的角度,来理解HTTP压缩这个概念。

    首先,浏览器发送一个请求(request)给web服务器,支持一个压缩格式如(gzip),服务端会将原来的源码压缩之后,通过http响应(response)信息返回给web浏览器,浏览器接收之后,显示出来。

    三、HTTP压缩的过程

    1. 浏览器发送Http request 给Web服务器,  request 中有Accept-Encoding: gzip, deflate。 (告诉服务器, 浏览器支持gzip压缩)

    2. Web服务器接到request后, 生成原始的Response, 其中有原始的Content-Type和Content-Length。

    3. Web服务器通过Gzip,来对Response进行编码, 编码后header中有Content-Type和Content-Length(压缩后的大小), 并且增加了Content-Encoding:gzip.  然后把Response发送给浏览器。

    4. 浏览器接到Response后,根据Content-Encoding:gzip来对Response 进行解码。 获取到原始response后, 然后显示出网页。
    如下图:

    HTTP压缩,浏览器是如何解析的

    四、内容编码类型

    HTTP定义了一些标准的内容编码类型,并允许用扩展的形式添加更多的编码。

    Content-Encoding header 就用这些标准化的代号来说明编码时使用的算法

    Content-Encoding值

    • gzip  表明实体采用GNU zip编码
    • compress 表明实体采用Unix的文件压缩程序
    • deflate  表明实体是用zlib的格式压缩的
    • identity  表明没有对实体进行编码。当没有Content-Encoding header时, 就默认为这种情况

    gzip, compress, 以及deflate编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息损失。 其中gzip通常效率最高, 使用最为广泛。

    压缩的好处

    http压缩对纯文本可以压缩至原内容的40%, 从而节省了60%的数据传输。

    Gzip的缺点

    JPEG这类文件用gzip压缩的不够好。

    Gzip是如何压缩的

    简单来说, Gzip压缩是在一个文本文件中找出类似的字符串, 并临时替换他们,使整个文件变小。这种形式的压缩对Web来说非常适合, 因为HTML和CSS文件通常包含大量的重复的字符串,例如空格,标签。

    HTTP Response能压缩,HTTP Request也是可以压缩的

    浏览器是不会对Request压缩的。 但是 一些HTTP程序在发送Request时,会对其进行编码。

    五、HTTP压缩示例(Java)

        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String data = "abcdabcdabcdabcdabcdabcdab" + "cdabcdabcdabcdabcdabcdabcdabcdabc"
                    + "dabcdabcdabcdabcdabcdabcdabcdabc" + "dabcdabcdabcdabcdabcdabcdabcdabcdab"
                    + "cdabcdabcdabcdabcdabcdabcdabcdabcdab" + "cdabcdabcdabcdabcdabcdabcdabcdabcdab"
                    + "cdabcdabcdabcdabcdabcdabcdabcdabcdab" + "cdabcdabcdabcdabcdabcdabcdabcdabcdabcd";
    
            System.out.println("原始数据的大小为:" + data.getBytes().length);
    
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            GZIPOutputStream gout = new GZIPOutputStream(bout); // buffer
            gout.write(data.getBytes());
            gout.close();
            // 得到压缩后的数据
            byte g[] = bout.toByteArray();
    
            // 浏览器一般支持gzip、deflate等压缩方式,其中gzip最广泛使用;
            // 没有设置此句的话浏览器访问时会直接弹出保存.gz文件的对话框,设置后浏览器会解压缩并显示
            response.setHeader("Content-Encoding", "gzip");
    
            // 此可以不设,不管有没有启用压缩,浏览器始终会根据内容大小自动设置Content-Length header
            response.setHeader("Content-Length", g.length + "");
    
            response.getOutputStream().write(g);
            System.out.println("压缩后数据的大小为:" + g.length);
        }
    View Code
    •  运行后,浏览器访问时会显示原始数据;查看响应信息如下,会有Content-Encoding:gzip

    •  服务端会打印如下信息:

  • 相关阅读:
    javascript通用循环遍历方法forEach
    伪数组
    引用和基本类型
    谈谈Javascript的this指针
    理解内存分配
    理解undefined和null
    getElementsByClassName实现
    NSubstitute完全手册(十五)自动递归模拟
    NSubstitute完全手册(十七)参数匹配器上的操作
    NSubstitute完全手册(九)检查接收到的调用
  • 原文地址:https://www.cnblogs.com/z-sm/p/5478495.html
Copyright © 2020-2023  润新知