HTTP协议那些不得不说的事

1 HTTP基础

1.1 http发展历程

HTTP1.1的特点:

  • 持久连接。 即在一次TCP连接中多次发送http请求(对应返回头里的Connection: keep-alive),较于http1.0每次http连接都要三次握手,大大减少了握手的时间消耗。浏览器一般允许一个url最多6个tcp连接(同域内),再多的请求就需要复用tcp连接了。
  • 但返回数据是类似串行的,即如果服务端对第二个请求的响应比第一个还快,那也必须等第一个请求返回结果后才能返回,这个在http2中得到解决。
  • 增加了host和其他命令。 通过host字段可以用来区分同一台物理服务器提供的不同web服务。

HTTP2的特点:

  • 引入信道复用和分帧传输,数据是以二进制传输的(之前传输的字符串)。得益于此,HTTP2可以在同一TCP连接上连续快速的发送多个请求,并且无序接收响应(类似于并行),无需客户端和服务器之间的多个连接,大大提高传输效率。
  • 引入头信息压缩等技术提高传输效率。将每次http请求都会包含的header信息压缩(如 accept,Content-Type等),节省带宽提高传输效率。
  • 提供了推送的功能。

HTTP2和HTTP1的性能在线比较网站HTTP2server push的性能比较,可以看出http2的性能提升主要原因在于信道复用和分帧传输技术。
在这里插入图片描述
在这里插入图片描述

1.2 发起一次请求浏览器端经历的过程

在这里插入图片描述
       浏览器发起请求所经过的各过程,先判断是否跳转,然后查看是否可以利用缓存,再根据域名解析IP,然后创建TCP连接,如果是https还要建立安全的连接,最后发出请求和接收响应数据。理解图中各节点有助于理解浏览器端原理,也可以根据耗时更好的判断性能优化点。

1.3 什么是跨域

       跨域是因为浏览器为了安全引入的同源限制策略:即浏览器限制页面内请求的url必须和地址栏的url处于同域上,也就是域名,端口,协议相同。注意其实跨域的请求已经发出,也接收到响应,但是浏览器拦截了。

  • 如何跨域?
    方法有很多。
    1.直接在服务器端设置允许跨域,即设置Access-Control-Allow-Orrigin:*可以允许跨域。
    2.利用jsonp,原理是AJAX直接请求普通文件存在跨域无权限访问的问题,不过我们在调用js文件的时候又不受跨域影响,所以在script中调用js凡是拥有scr这个属性的标签都可以跨域例如<script><img><iframe><link>等
    跨域比较复杂,这里简单了解。

1.4 数据协商:Accept 和Content

客户端和服务端传输数据时,需要协商和声明内容的格式,通过头来指定,下面介绍常见的几种header。

请求头 含义
Accept 客户端可接受的数据类型,如application/json, text/plain, */*
Accept-Encoding 可接受的编码格式,主要指压缩方式,如gzip, deflate, br
Accept-Language 支持的语言类型,如zh-CN,zh;q=0.9
User-Agent 客户端浏览器的信息
Content-Type 客户端提交时内容的类型

服务端返回响应时,从浏览器可接受的格式中选择一种返回,客户端浏览器根据响应头来进行解析。

响应头 含义
Content-Type 对应请求里的Accept,从可接受的数据格式中选择一种格式返回。开发中经常遇到application/json
Content-Encoding 对应请求里的Accept-Encoding,服务端返回内容的压缩方式
Content-Language 对应请求里的Accept-Language,服务端返回的语言类型

1.5 其他

  1. 302重定向
           302是重定向,在服务器端返回跳转地址。301是永久跳转地址,浏览器会缓存这个跳转地址,所以即使跳转地址变了浏览器还是会去之前那个跳转地址,直到清除浏览器缓存!

  2. Content-Security-Policy(CSP安全策略)
           Content-Security-Policy头是控制网站资源获取的一种安全策略,可以限制资源获取权限,向服务器报告资源获取越权。可以通过default-src限制网站请求的url,可以限制资源类型(如图片,media,font,script等等)。如通过Content-Security-Policy :'default-src http: https:'来限制只允许页面的http或https的请求,禁止脚本js代码执行请求。这个头支持很多安全策略,这里只做简单了解。

  3. URI、URL区别
           URI:统一资源标识符,包含URL和URN,是更抽象的概念。
           URL协议的常见格式:协议://主机地址:端口/path?query=string#hash ,如https://mp.csdn.net/mdeditor/8299#。协议包含http、ftp、file等;主机地址(ip或域名);端口为80时可省略,web服务端口一般为80;路由即文件路径或文件名有默认值(如index.html),可省略;后面可添加一些查询参数。可查看我的另一篇文章http从发出请求到接收响应的过程

  4. 浏览器F12更多技巧:
    a). 可以根据多种属性来筛选请求
    在这里插入图片描述注意:这里的h2就代表了HTTP2的协议请求。connection-id代表tcp连接,不同的id对应一个新的tcp连接。
    b). 选择Fast 3G可以模拟网速较慢时候请求的情况,说不定会用到。
    c). 勾选Disable cache就会强制不使用缓存。
    在这里插入图片描述

2. 关于浏览器缓存那些事

2.1 cache-control 缓存策略

cache-control 头可以设置很多值,根据类别有如下几种:

  1. public、 private、 no-cache可缓存性

       首先要知道在响应的返回内容所经过的网络服务或者路径中,有各种代理,缓存服务器等等(查看我的另一篇文章http从发出请求到接收响应的过程)。

  • public:返回经过的任何一个节点(代理,缓存服务器)都可以缓存;
  • private:只有发起请求的浏览器才可以缓存;
  • no-cache:指本地可以使用缓存,但是每次要经过服务器验证。也就是每次请求必须要到服务器进行验证,服务器回复可以使用缓存,客户端浏览器才可以使用本地缓存。no-cahce是最常用的策略,稍后会重点分析验证的过程。
  1. max-age 过期时间
           max-age设置缓存的过期时间,在时间过期之前,浏览器不会到服务器进行验证,即使服务器内容已经改变!解决办法有,打包后的js文件夹名根据js的内容生成hash码来命名。这样如果服务器端js文件有变化,则js的路径也会变化,也就是嵌入到页面内的url也会变化,所以浏览器就会根据新的url去请求js或静态资源而不是利用缓存了。
           s-maxage专门为代理服务设置的过期时间设置。

  2. must-revalidate 重新验证
            指max-age时间过期后,必须要请求服务验证。 proxy-revalidate相同的作用,只不过只用在代理服务器上。一般用不到这两个值,知道即可。

  3. no-store
           指永远不使用缓存,永远都要去服务器请求新的响应,和谷歌浏览器中勾选Disable cache作用类似。注意和no-cache的区别。
           no-transform 只用于代理服务器,告诉它不要瞎改服务器返回的内容(比如自作聪明的压缩、分割、转换了)

       注意:以上这些策略只是规范,而不是强约束。可以设置多个值,逗号分隔。

no-cache验证可用性的具体过程:
       首先客户端使用缓存的大概流程如下:
在这里插入图片描述
使用no-cache,每次请求都会向服务器验证缓存,这里涉及到两个头Last-Modified和Etag。
        Last-Modified上次修改时间,浏览器请求后,服务器返回资源时会带上一个响应头Last-Modified指定一个时间。当浏览器再次请求时会通过If-Modified-Since头携带前面服务器返回的时间,然后服务器收到后和本地的修改时间做对比,如果等于上次修改的时间,说明资源没有变化,服务器就会告诉客户端浏览器可以使用你本地的缓存(即返回状态码304!!)。
        Etag是更加严格的验证,它会对资源作签名(如对资源内容进行hash)。同样的,服务器在返回资源时,响应头会带上Etag(hash生成的一个随机串)。然后浏览器再次请求时通过If-None-Match或If-Match携带这个随机串,服务器会进行比较,如果两个摘要随机串相同说明资源没有变更,就会回复客户端浏览器可以使用你本地的缓存(即返回状态码304!!)。

3. cookie

cookie的作用不再赘述,服务器通过set-cookie来设置cookie,cookie是键值对的形式,可以设置多个,浏览器下次请求就会带上cookie。

cookie还有多种属性:max-age和expires来控制cookie的过期时间;Secure指定cookie只在https时发送;HTTPOnly设置无法通过document.cookie来访问,这个是为了防止重要的cookie数据被恶意js代码来访问,预防XFS攻击;domain来设置cookie的域,如可以在一级域名test.com对应的服务器中设置cookie,这样去访问二级域名a.test.com或者b.test.com的服务器时,也可以携带cookie,即实现了共享cookie。

原文地址:https://www.cnblogs.com/seasail/p/12179356.html