深圳网站设计哪家,网站设计优缺点,页面设计在线,广州网站设计有哪些专业目录
1. HTTP传输大文件的方法
1.1. 数据压缩
1.2. 分块传输
1.3. 范围请求
1.4. 多段数据
2. HTTP的连接管理
2.1. 短连接
2.2. 长连接
2.3. 队头阻塞
3. HTTP的重定向和跳转
3.1. 重定向的过程
3.2. 重定向状态码
3.3. 重定向的应用场景
3.4. 重定向的相关问题…目录
1. HTTP传输大文件的方法
1.1. 数据压缩
1.2. 分块传输
1.3. 范围请求
1.4. 多段数据
2. HTTP的连接管理
2.1. 短连接
2.2. 长连接
2.3. 队头阻塞
3. HTTP的重定向和跳转
3.1. 重定向的过程
3.2. 重定向状态码
3.3. 重定向的应用场景
3.4. 重定向的相关问题 1. HTTP传输大文件的方法
如何在有限的带宽下高效快捷地传输这些大文件:
压缩 HTML 等文本文件是传输大文件最基本的方法分块传输可以流式收发数据节约内存和带宽使用响应头字段“Transfer-Encoding: chunked”来表示分块的格式是 16 进制长度头 数据块范围请求可以只获取部分数据即“分块请求”实现视频拖拽或者断点续传使用请求头字段“Range”和响应头字段“Content-Range”响应状态码必须是 206也可以一次请求多个范围这时候响应报文的数据类型是“multipart/byteranges”body 里的多个部分会用 boundary 字符串分隔。 1.1. 数据压缩
通常浏览器在发送请求时都会带着“Accept-Encoding”头字段里面是浏览器支持的压缩格式列表例如 gzip、deflate、br 等这样服务器就可以从中选择一种压缩算法放进“Content-Encoding”响应头里再把原数据压缩后发给浏览器。 不过这个解决方法也有个缺点gzip 等压缩算法通常只对文本文件有较好的压缩率而图片、音频视频等多媒体数据本身就已经是高度压缩的再用 gzip 处理也不会变小甚至还有可能会增大一点所以它就失效了。 不过数据压缩在处理文本的时候效果还是很好的所以各大网站的服务器都会使用这个手段作为“保底”。例如在 Nginx 里就会使用“gzip on”指令启用对“text/html”的压缩。 1.2. 分块传输
把大文件“拆开”分解成多个小块把这些小块分批发给浏览器浏览器收到后再组装复原。
这种“化整为零”的思路在 HTTP 协议里就是“chunked”分块传输编码在响应报文里用头字段“Transfer-Encoding: chunked”来表示意思是报文里的 body 部分不是一次性发过来的而是分成了许多的块chunk逐个发送。 分块传输也可以用于“流式数据”例如由数据库动态生成的表单页面这种情况下 body 数据的长度是未知的无法在头字段“Content-Length”里给出确切的长度所以也只能用 chunked 方式分块发送。 “Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的也就是说响应报文里这两个字段不能同时出现一个响应报文的传输要么是长度已知要么是长度未知。 分块传输的编码规则
每个分块包含两个部分长度头和数据块长度头是以 CRLF回车换行即\r\n结尾的一行明文用 16 进制数字表示长度数据块紧跟在长度头后最后也用 CRLF 结尾但数据不包含 CRLF最后用一个长度为 0 的块表示结束即“0\r\n\r\n”。 分块传输示例
不过浏览器在收到分块传输的数据后会自动按照规则去掉分块编码重新组装出内容所以想要看到服务器发出的原始报文形态就得用 Telnet 手工发送请求或者用 Wireshark 抓包 16进制0123456789abcdef
1.3. 范围请求
如果想获取一个大文件其中的片段数据需要使用“范围请求”range requests。
范围请求允许客户端在请求头里使用专用字段来表示只获取文件的一部分相当于是客户端的“化整为零”。 范围请求不是 Web 服务器必备的功能可以实现也可以不实现所以服务器必须在响应头里使用字段“Accept-Ranges: bytes”明确告知客户端“我是支持范围请求的”。 如果不支持的话服务器可以发送“Accept-Ranges: none”或者干脆不发送“Accept-Ranges”字段这样客户端就认为服务器没有实现范围请求功能只能收发整块文件。 请求头Range是 HTTP 范围请求的专用字段格式是“bytesx-y”其中的 x 和 y 是以字节为单位的数据范围。
范围请求示例 1.4. 多段数据
范围请求还支持在 Range 头里使用多个“x-y”一次性获取多个片段数据。
这种情况需要使用一种特殊的 MIME 类型“multipart/byteranges”表示报文的 body 是由多段字节序列组成的并且还要用一个参数“boundaryxxx”给出段之间的分隔标记。
多段数据的格式与分块传输也比较类似但它需要用分隔标记 boundary 来区分不同的片段。 范围请求多段数据示例 2. HTTP的连接管理
早期的 HTTP 协议使用短连接收到响应后就立即关闭连接效率很低HTTP/1.1 默认启用长连接在一个连接上收发多个请求响应提高了传输效率服务器会发送“Connection: keep-alive”字段表示启用了长连接报文头里如果有“Connection: close”就意味着长连接即将关闭过多的长连接会占用服务器资源所以服务器会用一些策略有选择地关闭长连接“队头阻塞”问题会导致性能下降可以用“并发连接”和“域名分片”技术缓解。
2.1. 短连接
HTTP 协议最初0.9/1.0是个非常简单的协议通信过程也采用了简单的“请求 - 应答”方式。
它底层的数据传输基于 TCP/IP每次发送请求前需要先与服务器建立连接收到响应报文后会立即关闭连接。因为客户端与服务器的整个连接过程很短暂不会与服务器保持长时间的连接状态所以就被称为“短连接”short-lived connections。早期的 HTTP 协议也被称为是“无连接”的协议。
在短连接中 TCP 协议频繁的建立连接和关闭连接时间浪费严重效率很低。 2.2. 长连接
“长连接”也叫“持久连接”persistent connections、“连接保活”keep alive、“连接复用”connection reuse可以有效解决短连接的缺点。 在短连接里发送了三次 HTTP“请求 - 应答”每次都会浪费 60% 的 RTT 时间。而在长连接的情况下同样发送三次请求因为只在第一次时建立连接在最后一次时关闭连接所以浪费率就是“3÷9≈33%”降低了差不多一半的时间损耗。 HTTP/1.1 中的连接都会默认启用长连接。不需要用什么特殊的头字段指定只要向服务器发送了第一次请求后续的请求都会重复利用第一次打开的 TCP 连接也就是长连接在这个连接上收发数据。
不过不管客户端是否显式要求长连接如果服务器支持长连接它总会在响应报文里放一个“Connection: keep-alive”字段告诉客户端“我是支持长连接的接下来就用这个 TCP 一直收发数据吧”。 长连接的缺点
TCP 连接长时间不关闭服务器必须在内存里保存它的状态这就占用了服务器的资源。如果有大量的空闲长连接只连不发就会很快耗尽服务器的资源导致服务器无法为真正有需要的用户提供服务。
长连接缺点的解决方法
在客户端可以在请求头里加上“Connection: close”字段告诉服务器“这次通信后就关闭连接”。服务器看到这个字段就知道客户端要主动关闭连接于是在响应报文里也加上这个字段发送之后就调用 Socket API 关闭 TCP 连接。服务器端通常不会主动关闭连接但也可以使用一些策略。以 Nginx 为例它有两种方式
使用“keepalive_timeout”指令设置长连接的超时时间如果在一段时间内连接上没有任何数据收发就主动断开连接避免空闲连接占用系统资源。使用“keepalive_requests”指令设置长连接上可发送的最大请求次数。比如设置成 1000那么当 Nginx 在这个连接上处理了 1000 个请求后也会主动断开连接。
2.3. 队头阻塞
“队头阻塞”与短连接和长连接无关而是由 HTTP 基本的“请求 - 应答”模型所导致的。 因为 HTTP 规定报文必须是“一发一收”这就形成了一个先进先出的“串行”队列。队列里的请求没有轻重缓急的优先级只有入队的先后顺序排在最前面的请求被最优先处理。 如果队首的请求因为处理的太慢耽误了时间那么队列里后面的所有请求也不得不跟着一起等待结果就是其他的请求承担了不应有的时间成本。 性能优化
1. 并发连接对一个域名发起多个长连接用数量来解决质量的问题。
但这种方式也存在缺陷。如果每个客户端都想自己快建立很多个连接用户数×并发数就会是个天文数字。服务器的资源根本就扛不住或者被服务器认为是恶意攻击反而会造成“拒绝服务”。
2. 域名分片多开几个域名比如 shard1.chrono.com、shard2.chrono.com而这些域名都指向同一台服务器 www.chrono.com这样实际长连接的数量就又上去了。
3. HTTP的重定向和跳转
重定向是服务器发起的跳转要求客户端改用新的 URI 重新发送请求通常会自动进行用户是无感知的301/302 是最常用的重定向状态码分别是“永久重定向”和“临时重定向”响应头字段 Location 指示了要跳转的 URI可以用绝对或相对的形式重定向可以把一个 URI 指向另一个 URI也可以把多个 URI 指向同一个 URI用途很多使用重定向时需要当心性能损耗还要避免出现循环跳转。 “超文本”里含有“超链接”可以从一个“超文本”跳跃到另一个“超文本”用户可以在查看时随意点击链接、转换页面。点击页面“链接”时浏览器首先要解析链接文字里的 URI再用这个 URI 发起一个新的 HTTP 请求获取响应报文后就会切换显示内容渲染出新 URI 指向的页面。
这样的跳转动作是由浏览器的使用者主动发起的可以称为“主动跳转”但还有一类跳转是由服务器发起的浏览器使用者无法控制相对地就可以称为“被动跳转”这在 HTTP 协议里有个专门的名词叫做“重定向”Redirection。
3.1. 重定向的过程
在实验环境下用Chrome浏览器打开“http://www.chrono.com/18-1”。 “Location”字段属于响应字段必须出现在响应报文里。但只有配合 301/302 状态码才有意义它标记了服务器要求重定向的 URI这里就是要求浏览器跳转到“index.html”。
浏览器收到 301/302 报文会检查响应头里有没有“Location”。如果有就从字段值里提取出 URI发出新的 HTTP 请求相当于自动替我们点击了这个链接。 在“Location”里的 URI 既可以使用绝对 URI也可以使用相对 URI。所谓“绝对 URI”就是完整形式的 URI包括 scheme、host:port、path 等。所谓“相对 URI”就是省略了 scheme 和 host:port只有 path 和 query 部分是不完整的但可以从请求上下文里计算得到。 实验环境的 URI“/18-1”还支持使用 query 参数“dstxxx”指明重定向的 URI。
在重定向时如果只是在站内跳转你可以放心地使用相对 URI。但如果要跳转到站外就必须用绝对 URI。 例如如果想跳转到 Nginx 官网就必须在“nginx.org”前把“http://”都写出来否则浏览器会按照相对 URI 去理解得到的就会是一个不存在的 URI“http://www.chrono.com/nginx.org” http://www.chrono.com/18-1?dstnginx.org # 错误 http://www.chrono.com/18-1?dsthttp://nginx.org # 正确 3.2. 重定向状态码
301俗称“永久重定向”Moved Permanently意思是原 URI 已经“永久”性地不存在了今后的所有请求都必须改用新的 URI。 浏览器看到 301就知道原来的 URI“过时”了就会做适当的优化。比如历史记录、更新书签下次可能就会直接用新的 URI 访问省去了再次跳转的成本。搜索引擎的爬虫看到 301也会更新索引库不再使用老的 URI。 302俗称“临时重定向”“Moved Temporarily”意思是原 URI 处于“临时维护”状态新的 URI 是起“顶包”作用的“临时工”。 浏览器或者爬虫看到 302会认为原来的 URI 仍然有效但暂时不可用所以只会执行简单的跳转页面不记录新的 URI也不会有其他的多余动作下次访问还是用原 URI。 301/302 是最常用的重定向状态码在 3××里还有
303 See Other类似 302但要求重定向后的请求改为 GET 方法访问一个结果页面避免 POST/PUT 重复操作307 Temporary Redirect类似 302但重定向后请求里的方法和实体不允许变动含义比 302 更明确308 Permanent Redirect类似 307不允许重定向后的请求变动但它是 301“永久重定向”的含义。
不过这三个状态码的接受程度较低有的浏览器和服务器可能不支持开发时应当慎重测试确认浏览器的实际效果后才能使用。
3.3. 重定向的应用场景
什么时候需要重定向
1. 资源不可用”需要用另一个新的 URI 来代替。 例如域名变更、服务器变更、网站改版、系统维护这些都会导致原 URI 指向的资源无法访问为了避免出现 404就需要用重定向跳转到新的 URI继续为网民提供服务。 2. “避免重复”让多个网址都跳转到一个 URI增加访问入口。 例如有的网站都会申请多个名称类似的域名然后把它们再重定向到主站上。 重定向状态码如何选择
1. 301 的含义是“永久”的。 如果域名、服务器、网站架构发生了大幅度的改变比如启用了新域名、服务器切换到了新机房、网站目录层次重构这些都算是“永久性”的改变。原来的 URI 已经不能用了必须用 301“永久重定向”通知浏览器和搜索引擎更新到新地址这也是搜索引擎优化SEO要考虑的因素之一。 2. 302 的含义是“临时”的。 原来的 URI 在将来的某个时间点还会恢复正常常见的应用场景就是系统维护把网站重定向到一个通知页面告诉用户过一会儿再来访问。另一种用法就是“服务降级”比如在双十一促销的时候把订单查询、领积分等不重要的功能入口暂时关闭保证核心服务能够正常运行。 3.4. 重定向的相关问题
1. 性能损耗
重定向的机制决定了一个跳转会有两次请求 - 应答比正常的访问多了一次。 虽然 301/302 报文很小但大量的跳转对服务器的影响也是不可忽视的。站内重定向还好说可以长连接复用站外重定向就要开两个连接如果网络连接质量差那成本可就高多了会严重影响用户的体验。 所以重定向应当适度使用决不能滥用。
2. 循环跳转
如果重定向的策略设置欠考虑可能会出现“ABCA”的无限循环不停地在这个链路里转圈圈。
所以 HTTP 协议特别规定浏览器必须具有检测“循环跳转”的能力在发现这种情况时应当停止发送请求并给出错误提示。 实验环境的 URI“/18-2”就模拟了这样的一个“循环跳转”它跳转到“/18-1”并用参数“dst/18-2”再跳回自己实现了两个 URI 的无限循环。结果如下