HTTP协议那些不得不说的问题

本文主要是讲一些HTTP常见的问题,可能不够系统,欢迎小伙伴们指出。
如果后续有时间,我会从底层详细梳理一下TCP/IP协议栈的内容。

主要内容

  • HTTP状态码
  • HTTP的短连接、长连接
  • HTTP是无状态的,怎么保持状态
  • HTTP和HTTPS
  • HTTP/2.0
  • GET和POST的区别

1、HTTP状态码

状态码
常见的状态码

1XX

100 Continnue:表面到目前为止都很正常,客户端可以继续发送请求

2XX

200 OK:请求被正常处理
204 No Content:客户端的请求被服务器正常处理,服务器没有内容可返回
206 Partial Content:表示客户端进行了范围请求,服务器返回由Content-Range指定范围的内容

3XX

301 Moved Permanently:永久重定向,表示资源被永久的移动到了其他为止,也就是说重新分配了URL
302 Found:临时重定向,表示所请求资源暂时分到了新的URL
303 See Other:和302类型,但是明确要求客户端采用GET方法获取资源。
注:有关于GET和POST的区别,后续文章会指明
307 Temporary Redirect:临时重定向,和302类似 ,但是要求浏览器不能将重定向请求的POST方法改为GET方法。

4XX

400 Bad Request:客户端请求中有语法或参数错误,服务器无法识别
401 Unauthorized:请求中需要有认证信息。如果已经发送过一次该请求,则表示用户认证失败。
403 Forbidden:请求的资源禁止被访问
404 Not Found:服务器找不到客户端请求的资源(也可能是不想让客户端访问)

5XX

500 Internal Server Error:服务器内部错误
503 Service Unavailable:服务器暂处于超负载或停机维护,无法处理请求。

2、短连接还是长连接?

重点
我们所说的HTTP的长连接、短连接本质上是TCP的长短连接,因为TCP是双全工的,可以保持一段时间不关闭。说到底HTTP是一个应用层协议,而TCP才是传输层协议。

短连接

短链接就时说当浏览器访问到的某个HTML或其他类型的Web页面中包含有其他的Web资源(如js文件,图片文件,css文件等),那么每次请求这样一个web资源,都会建立一个Http会话
优点:管理简单,存在的都是有效连接,不需要额外的控制
缺点:如果用户请求频繁,那么会在TCP的建立和断开上消耗很多时间和带宽
适用场景:Web网站的http服务。如果使用长连接,那么并发量大的时候,每个用户都占用一个连接,那就gg了。

长连接

长连接指的是,当一个网页打开完成后,客户端和服务端传输数据的TCP连接并不会马上断开,当客户端再次访问这个服务器时,会使用这条已经存在的连接。当然保持连接(keep-Alive)不是永久保持,可以设定它的保持时间,由不同的服务器软件设置。
优点:节省了很多tcp建立和断开的操作,减少浪费。
缺点:服务器有个保活功能,如果客户端连接已经消失,那么服务器就会保留一个半开放的连接,保活功能就是在服务器探测这种连接,要么重新与客户端建立连接,那么释放这个连接。但是这个过程比较费时间,而且只是探测是否存活,如果存在恶意连接这个功能就没什么用了。所以还需要一些其他的策略,比如server端关闭长时间没有数据读写的连接,客户端限制最大长连接数等关闭策略,
适用场景:操作频繁,点对点通信,连接数不能太多。利用数据库使用长连接,短连接频繁的通信会造成socket错误,而且频繁创建socket也是很浪费资源的。

  • HTTP/1.0默认是短链接的。
  • HTTP/1.1默认长连接,使用长连接的协议会在头部加入Connection:Keep-Alive,如果想要断开,可由服务器或客户端断开,使用Connection:close
    使用浏览器开发者工具可以看到网页请求时头部的参数:
    在这里插入图片描述

HTTP/1.1长连接的两种工作方式
非流水方式(默认):HTTP的请求是按顺序发出的,下一个请求只有在当前请求得到响应后才能发出。但是收到网络延迟和带宽的影响,下一个请求被发送到服务器之前可能要等待很长时间。
流水方式:在同一条长连接上连续发送请求,而不需要等待响应返回。可以减少延迟。

3、HTTP是无状态的

HTTP是无状态的,指的是对事务的处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开服务器的一个网页和上次打开的网页之间没有关系。HTTP是一个无状态的面向连接的协议,当然无状态不能说明它不能保持TCP连接,更不能说明它是基于UDP的。HTTP的无状态是为了让它尽可能的简单,处理大量的事务。

那么现在我们登录一个网站比如淘宝,为什么它可以知道你上一次登录的用户是谁,知道返回属于哪个用户的信息呢?如果网页之间没有任何关系,那我们岂不是每换一个网页都要重新登录一次。那么从实际来看是不需要的,这里就要引入cookie和session了。

Cookie

HTTP/1.1引入了cookie来保存状态信息。cookie就是服务器发送给客户端并保存在本地的一小段数据,在下一次访问同一浏览器的时候就会携带上,告诉服务器两次请求来自于同一个浏览器。由于之后的每次请求都需要进行带上cookie,所以会带来额外的性能开销。

使用场景

  • 会话状态管理(如用户登录状态,购物车,游戏分数等需要记录的数据)
  • 个性化设置(如用户自定义设置)
  • 浏览器行为分析(跟踪用户的行为)

分类

  • 会话期cookie:尽在会话期间有效,浏览器关闭后自动删除
  • 持久性cookie:指定过期时间和有效期后就成了持久性cookie

Session

除了可以将信息通过cookie保存在本地浏览器中,也可以利用session保存在服务器上,而且存储在服务器上的信息更加安全。
Session可以存储在服务器的文件,数据库或内存中。比如存储在Redis中,效率更高。
使用session维护用户登录状态的过程如下:

  • 用户登录时,提交包含用户名和密码的表单,放入HTTP请求报文中。
  • 服务器验证用户名和密码,如果正确则把用户信息存储到Redis中,它在Redis中的Key称为Session ID
  • 服务器返回报文的Set-cookie包含了这个Session Id,客户端收到后将该Cookie值存入浏览器中。
  • 客户端之后对同一个服务器的请求会包含该cookie值,服务器收到后提取出其中的Session Id,从Redis中取出用户信息,继续之前的操作。

应该注意 Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下,例如转账等操作,除了使用 Session 管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。

浏览器禁用Cookie

如果浏览器禁用cookie的话,此时只能使用Session来保存用户信息。而且此时不能使用cookie来保存Session ID ,而是使用URL重写技术,将Session ID作为URL的参数来传递。

Cookie和Session的选择

  • Cookie 只能存储 ASCII 码字符串,而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选 Session;
  • Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密;
  • 对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。

4、HTTP和HTTPS

HTTP存在以下的安全性问题:

  • 采用明文通信,内容可能会被窃听。
  • 不验证通信方的身份,通信方的身份可能遭到伪装。
  • 无法证明报文的完整性,报文内容可能遭到篡改

HTTPS并不是一个新的协议,而是先让HTTP和SSL进行通信,再有SSL和TCP通信,保证了数据的安全性。
使用SSL,让HTTP有了加密(防窃听)、认证(防伪装)、和完整性保护(防篡改)。

SSL(还有TLS):是一种为网络通信提供安全和数据完整性的安全协议,在传输层和应用层之间为网络连接提供加密。

加密

加密算法的具体大家可以去研究一些,但是常见的加密方式可分为三类:对称加密、非对称加密、单向加密(如MD5)

1、对称密钥加密

对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥。

  • 优点:运算速度快;
  • 缺点:无法安全地将密钥传输给通信方。

2、非对称密钥加密

非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥。

公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。

非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。

  • 优点:可以更安全地将公开密钥传输给通信发送方;
  • 缺点:运算速度慢。

HTTPS采用的加密方式

上面提到对称密钥加密方式的传输效率更高,但是无法安全地将密钥 Secret Key 传输给通信方。而非对称密钥加密方式可以保证传输的安全性,因此我们可以利用非对称密钥加密方式将 Secret Key 传输给通信方。HTTPS 采用混合的加密机制,正是利用了上面提到的方案:

  • 使用非对称密钥加密方式,传输对称密钥加密方式所需要的 Secret Key,从而保证安全性;
  • 获取到 Secret Key 后,再使用对称密钥加密方式进行通信,从而保证效率。

认证(防伪装)

通过使用 证书 来对通信方进行认证。

数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。

服务器的运营人员向 CA 提出公开密钥的申请,CA 在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。

进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。

完整性

SSL 提供报文摘要功能来进行完整性保护。

HTTP 也提供了 MD5 报文摘要功能,但不是安全的。例如报文内容被篡改之后,同时重新计算 MD5 的值,通信接收方是无法意识到发生了篡改。

HTTPS 的报文摘要功能之所以安全,是因为它结合了加密和认证这两个操作。试想一下,加密之后的报文,遭到篡改之后,也很难重新计算报文摘要,因为无法轻易获取明文。

HTTPS的缺点

  • 因为要进行加密和解密,所以速度会更慢
  • 需要支付授权证书的高额费用

5、HTTP/2.0

HTTP/1.X的缺点

  • 客户端需要多个连接才能实现数据的并发和缩短延迟
  • 不会压缩请求和响应的头部,会产生额外的网络流量
  • 不支持有效的资源优先级,而使底层的TCP连接的利用率低下

HTTP/2.0的特性

二进制分层

HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式的。

在通信过程中,只会有一个 TCP 连接存在,它承载了任意数量的双向数据流(Stream)。

  • 一个数据流(Stream)都有一个唯一标识符和可选的优先级信息,用于承载双向信息。
  • 消息(Message)是与逻辑请求或响应对应的完整的一系列帧。
  • 帧(Frame)是最小的通信单位,来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装。

服务端推送

HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客户端请求 page.html 页面,服务端就把 script.js 和 style.css 等与之相关的资源一起发给客户端。

首部压缩

HTTP/1.1 的首部带有大量信息,而且每次都要重复发送。

HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见过的首部字段表,从而避免了重复传输。

不仅如此,HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。

6、GET和POST的区别

首先GET和POST都是http协议中的两种请求方式,GET一般是用来获取服务器信息的,而POST一般是用来更新信息的。
那么既然都是HTTP的请求方式,那么可以很容易想到POST和GET也是基于TCP的,所以本质上没有什么区别。
先说以下区别:

  • GET请求的速度比POST的快
  • GET请求静态资源的话会被浏览器主动缓存,而POST不会,除非手动设置。
  • GET请求会将数据放在url之后,而POST则放在方法体中
  • GET请求在url中传送参数长度是有限制的,而POST则没有
  • 参数类型的话,GET只接受ASCII,而POST没有限制
  • POST比GET安全,因为GET参数暴露在url中,所以不能传输敏感信息

那么我们对其中一部分区别进行详细的说明一下

为什么GET比POST快

1、最重要的一点就是GET产生一个TCP数据包,而POST产生两个TCP数据包

  • 对于GET方式的请求,浏览器将header和data一并发送给服务器,返回200 OK(返回数据)。
  • 而对于POST方式的请求,浏览器将先发送header给服务器,服务器响应100 continue,继续发送data,服务器响应200 ok(返回数据)

因为POST要两步所以需要的时间多一点,但是并不意味着get比post更有效。

  • GET和POST有自己的语义不能乱用。
  • 网络好的情况下,发一次和发两次包的时间差基本可以忽略。而网络差的时候,两次发包在验证数据完整性上有很大的优点。
  • 并不是所有的浏览器都会分俩次发包,取决于浏览器的实现。

2、GET速度快的另一个原因是GET在请求静态资源的时候会进行缓存,而post不会。

GET传参的最大长度

1、首先HTTP协议中并没有规定GET和POST长度的限制
2、之所以出现最大长度是应为浏览器和web服务器设置了url的最大长度
3、而不同的浏览器和服务器设置的最大长度当然也可以是不同的

POST比GET安全

因为GET请求的参数会显示在URL中,那么用户使用浏览器的时候会缓存网页,这样别人查看浏览器的时候就会获取到用户的私人信息。而POST请求得参数放在请求体中,不会被看到,所以安全性更高。

当然这里说的安全是对用户来说得安全性。那么对服务器来说,GET反而是安全的,为什么?因为GET不会改变服务器的状态是只读的(Read Only)。而POST是传输实体内容是为了更新数据的,服务器将这个数据保存到数据库中,状态发生了改变,所以对服务器POST反而是不安全的。

好了终于写完了,感觉写的又臭又长,大家多多担待,如果有什么问题或者意见,欢迎评论留言,让我们一起进步!!!

参考文章:
HTTP
HTTP状态码
HTTP的短连接、长连接
GET和POST的区别
GET和POST的区别(这个写的生动易懂)
常见的加密算法

推荐:
GitHub上的一位巨佬,有自己总结的很多东西,大家感兴趣可以去看看(点击直达)
生动形象的讲解GET和POST的区别(易懂)

猜你喜欢

转载自blog.csdn.net/machine_Heaven/article/details/104690292