当前位置:首页>HTTP>HTTP报文>HTTP编码压缩提升传输速率

HTTP编码压缩提升传输速率

作者:微学网发布时间:2019-09-07 11:37:33

概述

http可以根据数据的原貌直接传输数据,但在传输过程中也可以通过编码来提高传输速率。

通过在传输时进行编码,可以有效地处理大量的访问请求。然而,编码的操作需要计算机来完成,因此会消耗更多的cpu和其他资源。

报文主体和实体主体的差异

  • 报文(message)
    是 HTTP 通信中的基本单位, 由 8 位组字节流(octet sequence,其中 octet 为 8 个比特) 组成, 通过 HTTP 通信传输。

  • 实体(entity)
    作为请求或响应的有效载荷数据(补充项) 被传输, 其内容由实体首部和实体主体组成。

HTTP 报文的主体用于传输请求或响应的实体主体。

通常, 报文主体等于实体主体。 只有当传输中进行编码操作时, 实体主体的内容发生变化, 才导致它和报文主体产生差异。

报文和实体这两个术语在之后会经常出现, 请事先理解两者的差异。

压缩传输的内容编码

向待发送邮件内增加附件时, 为了使邮件容量变小, 我们会先用 ZIP压缩文件之后再添加附件发送。 HTTP 协议中有一种被称为内容编码的功能也能进行类似的操作。

内容编码指明应用在实体内容上的编码格式, 并保持实体信息原样压缩。 内容编码后的实体由客户端接收并负责解码。

常用的内容编码有以下几种

  • gzip(GNU zip)

  • compress(UNIX 系统的标准压缩)

  • deflate(zlib)

  • identity(不进行编码)

分割发送的分块传输编码

在 HTTP 通信过程中, 请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。 在传输大容量数据时, 通过把数据分割成多块, 能够让浏览器逐步显示页面。

这种把实体主体分块的功能称为分块传输编码(Chunked Transfer Coding) 。

分块传输编码会将实体主体分成多个部分(块) 。 每一块都会用十六进制来标记块的大小, 而实体主体的最后一块会使用“0(CR+LF)”来标记。

使用分块传输编码的实体主体会由接收的客户端负责解码, 恢复到编码前的实体主体。

HTTP/1.1 中存在一种称为传输编码(Transfer Coding) 的机制, 它可以在通信时按某种编码方式传输, 但只定义作用于分块传输编码中。

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定义了一些标准的内容编码类型,并允许用扩展的形式添加更多的编码。

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) {
        String data = "abcdabcdabcdabcdabcdabcdab" + "cdabcdabcdabc"
                + "dabcdabcdabc" + "dabcdabcdabcdabcdabcdabcdabcdabcdab"
                + "cdabcbcdab" + "cdabcdabcdabcdabcdabcdabcdabcdabcdab"
                + "cdabcddab" + "cdabcdabbcdabcdabcdabcd";

        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);
    }

运行后,浏览器访问时会显示原始数据;查看响应信息如下,会有Content-Encoding:gzip

HTTP压缩