2、http和https
HTTP,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。HTTP 是应用层协议,它以 TCP(传输层)作为底层协议,默认端口为 80。
http的通信过程:服务器在80端口等待客户的请求;接着浏览器发起到服务器的TCP连接,服务器接受TCP连接,然后浏览器和服务器交换http消息,最后关闭TCP连接。
可以看出,http是基于tcp的。是可靠的,请求相应一一对应。
另外
HTTP协议是无状态协议:无状态指的是客户端发送HTTP请求给服务端之后,服务端根据请求响应数据,响应完后,不会记录任何信息。这种特性有优点也有缺点,缺点是无法共享数据。无状态的,因此无法做连续多个步骤的操作。例如:加入购物出,结算,支付。每次都需要验证身份信息,但是无状态所以无法连续。解决办法就是利用会话技术(Cookie、Session)。优点就是速度快。
HTTPS 协议(Hyper Text Transfer Protocol Secure),是 HTTP 的加强安全版本。HTTPS 是基于 HTTP 的,也是用 TCP 作为底层协议,并额外使用 SSL/TLS 协议用作加密和安全认证。可以理解成HTTPS = HTTP + SSL/TLS。默认端口号是 443。SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
SSL/TLS的核心要素是非对称加密。非对称加密采用两个密钥——一个公钥,一个私钥。在通信时,私钥仅由解密者保存,公钥由任何一个想与解密者通信的发送者(加密者)所知。
常用的非对称加密算法:RSA。
常见的对称加密算法有:DES、3DES和AES
在实际通信过程中,计算的代价较高,效率太低,因此,SSL/TLS 实际对消息的加密使用的是对称加密。
https的主要步骤:1、客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。2、Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端/。3、客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。4、客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。5、Web服务器利用自己的私钥解密出会话密钥。6、Web服务器利用会话密钥加密与客户端之间的通信。
结合了对称加密和非对称加密的方式。
数字签名实现完整性。数字证书CA实现身份认证。加密实现密文传输。
常见的状态码:
100-199 用于指定客户端应相应的某些动作。
200-299 用于表示请求成功。
300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。
400-499 用于指出客户端的错误。
500-599 用于支持服务器错误。
如果服务器收到头信息中带有100-continue的请求,这是指客户端询问是否可以在后续的请求中发送附件。
200 OK:客户端请求成功。
300表示被请求的文档可以在多个地方找到,并将在返回的文档中列出来。如果服务器有首选设置,首选项将会被列于定位响应头信息中。
301 状态是指所请求的文档在别的地方;文档新的URL会在定位响应头信息中给出。浏览器会自动连接到新的URL。永久重定向。
302:页面暂时性转移,表示资源或页面暂时转移到另一个位置,常被用作网址劫持或负载均衡
304 告诉客户端可以使用缓存资源
403 Forbidden:指的是服务器端有能力处理该请求,但是拒绝授权访问。404 Not Found:请求资源不存在,比如资源被删除了,或用户输入了错误的URL。
408 (Request Timeout/请求超时)
500 Internal Server Error:服务器发生不可预期的错误,一般是代码的BUG所导致的。500 (SC_INTERNAL_SERVER_ERROR) 是常用的“服务器错误”状态。该状态经常由CGI程序引起
502 (Bad Gateway/错误的网关)
503 服务器繁忙
HTTP 缓存技术
对于一些具有重复性的 HTTP 请求,比如每次请求得到的数据都一样的,我们可以把这对「请求-响应」的数据都缓存在本地,那么下次就直接读取本地的数据,不必在通过网络获取服务器的响应了。HTTP 缓存有两种实现方式,分别是强制缓存和协商缓存
强缓存指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的主动性在于浏览器这边。
强缓存是利用下面这两个 HTTP 响应头部(Response Header)字段实现的,它们都用来表示资源在客户端缓存的有效期:
Cache-Control, 是一个相对时间;
Expires,是一个绝对时间;
如果 HTTP 响应头部同时有 Cache-Control 和 Expires 字段的话,Cache-Control 的优先级高于 Expires
当我们在浏览器使用开发者工具的时候,你可能会看到过某些请求的响应码是 304,这个是告诉浏览器可以使用本地缓存的资源,通常这种通过服务端告知客户端是否可以使用缓存的方式被称为协商缓存。
3、get post put delete等区别
这些都是http定义的与服务器进行交互的不同方法。
从数据库角度来说,get相当于查询,从服务器查询相关数据; post是增加服务器的资源;delete是删除资源;put是修改服务器的资源。
还有其余的,head用来查询头部信息,不返回实体信息;trace用来回环诊断,回显服务器收到的请求,因为请求传递过程中会经过防火墙等,trace查看请求中途是否被更改;options允许客户端查看服务器性能;
由于put是幂等的,也就是如果两次请求相同,那么第二次会覆盖第一次,所以put用来更新资源;而post是非幂等的,不会覆盖,所以用来添加资源。
重点是get和post的区别和联系:
1.一个请求数据,一个上传数据;
2、安全性:get因为参数会放在url中,,get请求会保存在浏览器历史,可保存为书签,所以隐私性,安全性较差,post的数据在body中。
3、数据长度:由于get的请求放在url中,虽然http对url长度没有限制,但是服务器了浏览器有限制,一般在1024字节以内。因为长url解析消耗性能太大,并且容易收到恶意构造长url的攻击。post由于数据放在body中,所以没有限制。示例如下:
GET /updateInfo?name=Javanx&age=25 HTTP/1.1
Host: localhost
POST /updateInfo HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
name=Javanx&age=25
GET 和 POST 只是 HTTP 协议中两种请求方式(异曲同工),而 HTTP 协议是基于 TCP/IP 的应用层协议,无论 GET 还是 POST,用的都是同一个传输层协议,所以在传输上,没有区别。
但如果不按规范来也是可以的,可以在 URL 上写参数,然后方法使用 POST;也可以在 Body 写参数,然后方法使用 GET。当然,这需要服务端支持。
GET 方法参数写法是固定的吗?
在约定中,我们的参数是写在 ? 后面,用 & 分割。
我们知道,解析报文的过程是通过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。
POST 方法比 GET 方法安全?
有人说POST 比 GET 安全,因为数据在地址栏上不可见。
然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。
要想安全传输,就只有加密,也就是 HTTPS。
POST 方法会产生两个 TCP 数据包?
有些文章中提到,post 会将 header 和 body 分开发送,先发送 header,服务端返回 100 状态码再发送 body。
HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome)发现,header 和 body 不会分开发送。
所以,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为。
14. cookie,session区别
http是无连接的,这次请求和上次请求没有关系。但是如果需要数据共享,追踪用户行为(购物车)就需要知道用户信息。
cookie是一种存储在浏览器的字段信息,只有4kb,以键值对形式存在。一般访问流程:
用户http请求;服务器在响应头加一个set-cookie选项,里面包含cookie。之后用户再发送http请求时就会把cookie信息加在请求部分里面,服务器就会进行相应的业务响应。
session和cookie看起来很像。但是我们要分清session概念和session实现。session就是一个会话,相当于给服务器和浏览器建立一个连接。那么session的实现就是利用cookie为载体的,服务器会为每个浏览器产生一个独一的session id来标识连接,之后每次请求只要把id放在请求头部就可以知道浏览器是谁了。而一些用户信息上下文信息都是存储在服务器中,请求时只需要复制id就可以。而这个id往往就是通过cookie实现的。也就是说cookie是实现session id传递的载体之一。如果浏览器禁用cookie的话,session id也可以通过url重写实现。
所以综合来说,cookie很具体,就是一种服务器生成,存储在浏览器上的小字段,实现鉴权的具体方式。而session是一种宽泛的会话技术,通过session id标识,为服务器浏览器建立连接。
区别总结:
1、cookie存储在浏览器中,所以安全性较差,容易被劫持伪造;session只有id在浏览器中,具体信息存储在服务器中,安全性好一点,但是会增加服务器的负担,而且多个服务器的话负载均衡后很有可能找不到了。比如自动保存的密码等。
2、cookie只有4kb大小,只能存ASCII字符,而session存储信息不限,类型也很多。
15. 谈一谈http长连接、短连接、超时
明确一个概念,http是无状态的应用层协议,没有长短连接一说,请求响应和下一次没有关系的。这里的长连接实际上是指TCP连接。
短连接就是这一次请求响应结束后,下一次请求响应就要重新建立TCP连接。Connection:close就是短连接
长连接就是TCP连接不关闭,下一次请求响应就不用再三次握手四次挥手了,减少资源消耗,比如一次请求 HTML,可能还需要请求后续的 JS/CSS/图片等。http1.0默认是短连接,1.1默认是长连接。
一般长连接就是在请求头设置:Connection:keep-alive 和Keep-Alive: timeout=60。有timeout说明60s后连接失效,没有的话说明连接一直有效。
对于点对点的,交互频繁的。比如数据库就是长连接。对于web网页这种,用户很多,一般用短连接。不然的话会有成千上万的连接同时保存在服务器端。
长连接还有一个额外的问题,就是队头阻塞。在请求应答过程中,如果出现任何状况,剩下所有的工作都会被阻塞在那次请求应答之后。
解决办法:现代浏览器会针对单个域名开启6个连接,通过各个连接分别发送请求。它实现了某种程度上的并行,但治标不治本。
HTTP/2是完全多路复用的,而非有序并阻塞的。http2在一个连接上处理多个请求,实现流式传输,将请求分片,每个请求都有自己的id标识,到达服务器后再组装起来。这样就实现多路复用,提高效率。
超时的情况:请求超时,比如现在网络超级不好,当客户端发起一个请求,通信层开始请求与服务器建立连接(包括在重试),如果在5S之内还没有连接到服务器,那么认为超时。
响应超时一个不正确的url,将会响应404。或者服务器响应速度太慢,连接已经关闭。
http协议各个版本的演进
http1.0 默认是短连接,效率不高。
http1.1默认是长连接。另外,支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。(缺点:请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大;队头阻塞;请求只能从客户端开始,服务器只能被动响应)
http2的改进:(是基于https的)
头部压缩
HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分。
这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
二进制格式
HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(frame):头信息帧(Headers Frame)和数据帧(Data Frame)。
并行发送:针对不同的 HTTP 请求用独一无二的 Stream ID 来区分,接收端可以通过 Stream ID 有序组装成 HTTP 消息,不同 Stream 的帧是可以乱序发送的,因此可以并发不同的 Stream ,也就是 HTTP/2 可以并行交错地发送请求和响应。
服务器推送:客户端和服务器双方都可以建立 Stream, Stream ID 也是有区别的,客户端建立的 Stream 必须是奇数号,而服务器建立的 Stream 必须是偶数号。
HTTP/2 的缺点:
但是 HTTP/2 还是存在“队头阻塞”的问题,只不过问题不是在 HTTP 这一层面,而是在 TCP 这一层。一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。
HTTP/3 做了哪些优化
所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!
大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。
无队头阻塞
更快的连接建立
对于 HTTP/1 和 HTTP/2 协议,TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表示层,因此它们难以合并在一起,需要分批次来握手,先 TCP 握手,再 TLS 握手。
HTTP/3 在传输数据前虽然需要 QUIC 协议握手,但是这个握手过程只需要 1 RTT,握手的目的是为确认双方的「连接 ID」,连接迁移就是基于连接 ID 实现的。
但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,而是 QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的“记录”,再加上 QUIC 使用的是 TLS/1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商
连接迁移
而 QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID 来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。