HTTP协议进阶篇

·  阅读 126

如何传输大文件

  • 首先能想到的肯定是使用数据压缩,发送请求的时候会带有Accept-Encoding,里面是HTTP支持压缩的各种格式,比如gzip、deflate。服务器选择一种压缩算法放进Content-Encoding。gzip的压缩率通常对文本文件有60%的压缩率,但对音视频等多媒体文件的效果不是很好。
  • 分块传输也就是chunk,用字段Transfer-Encoding: chunked来表示。分块传输也可以用于流体数据,也就是body数据长度是未知的,无法给出“content-length”字段。
  • 范围请求可以只获得一个大文件的片段数据。范围请求不是服务器的必备功能,所以服务端必须在请求头中使用字段Accept-Ranges: bytes来告诉客户端,我是支持范围请求的。如果不支持范围请求的话,可以直接使用Accept-Ranges: none或者直接不发送Accept-Ranges字段,那么客户端就只能发送整块文件。
    • 请求头Range是HTTP范围请求的专用字段,格式是“bytes=x-y”。其中的x和y是以字节为单位的数据范围。收到range字段后,会做验证,如果范围不合法,则会返回416。如果范围正确,则返回206。服务器会添加一个响应字段content-range=bytes=x-y/length。
    • 如果是多段数据。支持在range头里添加多个x-y,一次性获得多个片段数据。这种情况需要使用一种特殊的 MIME类型:“multipart/byteranges”,表示报文的body是由多段字节序列组成的,并且还要用一个参数“boundary=xxx”给出段之间的分隔标记。如Content-Type: multipart/byteranges; boundary=00000000001

Cookie

Cookie是服务器委托浏览器存储的一些数据,让服务器有了“记忆能力”,主要用来解决HTTP是无状态的问题。利用响应头字段 Set-Cookie 和请求头字段 Cookie来实现cookie的传递,格式是“key=value”

设置Cookie的生存周期

“Expires”俗称“过期时间”,用的是绝对时间点
“Max-Age”用的是相对时间,单位是秒,浏览器用收到报文的时间点再加上 Max-Age,就可以得到失效的绝对时间。
当两者同时出现的时候会采用Max-Age计算失效时间。

设置cookie的作用域

“Domain”和“Path”指定了 Cookie 所属的域名和路径,浏览器在发送cookie之前会从URI提取出来host和path的部分,对比cookie的属性,如果不满足条件,则不会在请求头中发送cookie。

cookie的安全性

在JS脚本里可以用document.cookie来读写Cookie数据,这就带来了安全隐患,有可能会导致“跨站脚本”(XSS)攻击窃取数据。

  • HttpOnly: 此 Cookie只能通过浏览器HTTP协议传输,禁止其他方式访问。这是预防xss攻击的有效手段。
  • SameSite: 可以防范XSRF攻击。具体有三个值:
    • strict: 限定cookie不能随着跳转连接跨站发送
    • lax: 相对宽松一些,但是只能在get方法提交表单况或者a标签发送get请求的情况下可以携带 Cookie,其他情况均不能。
    • none: 请求会自动携带上Cookie
  • Secure: 表示这个 Cookie 仅能用 HTTPS 协议加密传输

缓存(Cache)

浏览器使用 HTTP 获取资源的成本较高。所以,非常有必要把“来之不易”的数据缓存起来,下次再请求的时候尽可能地复用。这样,就可以避免多次请求 - 应答的通信成本,节约网络带宽,也可以加快响应速度。服务器标识资源的有效期的头字段是Cache-Control,属性值如下:

  • max-age=30:最大有效时间是30s,过期后不可用
  • no-store:不允许缓存,比如秒杀页面
  • no-cache:可以缓存,但是用之前必须要去服务端验证资源是否过期
  • must-revalidate:可以缓存,过期时间内可用,过期后需要向服务端验证是否可用
  • private:缓存只能在客户端保存,是用户“私有”的,不能放在代理上与别人共享
  • public:缓存完全开放,谁都可以存,谁都可以用。

协商规则

强缓存

所谓强缓存的意思就是:如果缓存没有到期那么就用浏览器缓存,如果到期了,就重新去请求浏览器。
如何看缓存是否到期呢?也就是说,使用强缓存的规则是什么呢?就是上文提到的Cache-Control的值为max-age=xxx的情况。

协商缓存

触发协商缓存的条件是:Cache-Control的值为no-cache的情况。或者max-age到期了,比如max-age=0的情况。
那么协商缓存的过程是什么样的呢? 首先让我们来看两个字段,ETagLast-Modified
ETag:每个资源都有一个,文件发生改动则该值发生变化,是资源的唯一标识。ETag还有强弱之分,强ETag要求资源必须在字节级别完全相符,弱ETag在值前面有一个W/标识,只要求资源在语义上无变化,内部可以做顺序上的改动。 Last-Modified是文件最后修改的时间。
在第一次的请求中会提供ETag、Last-Modified这两个字段,下次请求的时候就带上这两个字段,但是名字变了,分别是ETag->If-None-MatchLast-Modified->If-Modified-since服务器来验证是否过期。如果资源没有变,服务器就返回304状态码,浏览器更新有效期之后,就可以放心的时候缓存了。如果资源有更改,返回200,返回最新的资源。

代理缓存

何为代理

HTTP协议中有两个通信方,分别是“请求方”浏览器和“应答方”服务器。我们在这个模型中引入一个新的角色,就是代理。在原本的通信链路中插入一个中间环节,也是一台服务器,提供代理服务。代理服务指的是服务本身不生产内容,而是处在中间位置转发上下游的请求和响应,具有双重身份。面对客户端的时候充当的是服务端的角色,面对源服务器的时候充当的是客户端的角色。代理最基本的功能是负载均衡
Via标记自己的身份,每当报文经过一个代理节点,代理服务器就会把自身的信息追加到字段的末尾。多个代理会形成一个列表;
X-Forwarded-For:为谁而转发,追加的是请求方的 IP 地址。记录客户端 IP 地址,没有中间的代理信息。

代理缓存的意义

之前谈到缓存的时候,大部分说的是客户端(浏览器)的缓存,它能够减少响应时间,节约带宽,提升客户端的用户体验。
但在http链路上,不仅客户端有缓存,服务器上的缓存也非常有价值,可以让请求不必走到源服务器处即可获取到资源。HTTP的服务器缓存功能主要由代理服务器来实现。

源服务器的缓存控制

must-revalidate是只要过期就必须回源服务器验证
proxy-revalidate只要求代理的缓存过期后必须验证,客户端不必回源,只验证到代理这个环节
s-maxage限定在代理上能够存多久,而客户端仍然使用“max-age” no-transform代理有时候会对缓存下来的数据做一些优化,比如把图片生成 png、webp 等几种格式,方便今后的请求处理,而“no-transform”就会禁止这样做,不许“偷偷摸摸搞小动作”。

客户端的缓存控制

缓存的生存时间,多了max-stalemin-fresh两个字段。“max-stale”的意思是如果代理上的缓存过期了也可以接受,但不能过期太多,超过 x 秒也会不要。“min-fresh”的意思是缓存必须有效,而且必须在 x 秒后依然有效。
only-if-cached表示只接受代理缓存的数据,不接受源服务器的响应

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改