我们在通过网络进行传输数据时,我们要保证,我们在发送时构造的数据,在接收时也能够解析出来,这本质上就是一种协议,是一种应用层协议,我们的程序员可以自定义这种协议,但实际上已经有大佬为我们写出了更靠谱的协议,就是HTTP。其是一种超文本传输协议。
那么这种协议到底是什么呢?
当我们去访问某个网页时,其先是会将我们的请求通过HTTP请求的方式,发送给服务器,然后服务器再回复给客户端对应的HTTP响应。
我们先来看HTTP请求中有什么。
其由首行+Header+Body组成。
我们先来看头部:
它由方法+url+版本组成。
那么什么是方法呢?
下图就是HTTP的方法
那么这些方法有什么区别呢?
我们以常用的GET和POST来说。GET请求的参数一般写在url中。URL 规定只能支持 ASCII,所以 GET 请求的参数只允许 ASCII 字符 ,而且浏览器会对 URL 的长度有限制,通常为2048个字符。(HTTP协议本身对 URL长度并没有做任何规定)。
POST 请求携带数据的位置一般是写在报文 body 中,body 中的数据可以是任意格式的数据,只要客户端与服务端协商好即可,而且浏览器不会对 body 大小做限制。
因为GET请求将参数放在URL中,所以容易泄漏信息,例如我们在网页上就行用户密码登录时,若用GET请求,就会将用户名和密码都显式在URL中,从而暴露了我们的个人信息。
在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源。
所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的。
如果从 RFC 规范定义的语义来看:
GET 方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。所以,可以对 GET 请求的数据做缓存,这个缓存可以做到浏览器本身上(彻底避免浏览器发请求),也可以做到代理上(如nginx),而且在浏览器中 GET 请求可以保存为书签。
POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。所以,浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签。
GET方法与POST方法的区别:
安全性:POST方法比GET方法更安全,因为它将数据作为请求主体发送,而不是明文暴露在URL中。
数据量:POST方法没有数据量限制,而GET方法受到URL长度的限制。
数据类型:POST方法可以发送各种类型的数据,而GET方法主要用于发送文本数据。
缓存:POST方法不会被浏览器缓存,而GET方法可能会被缓存。
我们再来谈谈URL。
我们平时所说的网址就是URL,其包括这几部分:
最后一个版本就是HTTP的版本,再进行通信时,不同的版本则应该对应用同一版本进行解析。
HTTP 是基于 TCP 传输协议进行通信的,而使用了 TCP 传输协议,就会存在一个“粘包”的问题,HTTP 协议通过设置回车符、换行符作为 HTTP header 的边界,通过 Content-Length 字段作为 HTTP body的边界,这两个方式都是为了解决“粘包”的问题
HTTP的响应包括:首行+Header+BODY.
我们来看首部:其包括版本号+状态码+状态码解释。
版本号我们上面提到过,那么什么是状态码呢?
「200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。
「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
「206 Partial Content」是应用于 HTTP 分块下载或断点续传,表示响应返回的 body数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
「302 Found」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。
「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思
对于一些具有重复性的 HTTP 请求,比如每次请求得到的数据都一样的,我们可以把这对「请求-响应」的数据都缓存在本地,那么下次就直接读取本地的数据,不必在通过网络获取服务器的响应了,这样的话 HTTP/1.1 的性能肯定肉眼可见的提升。
所以,避免发送 HTTP 请求的方法就是通过缓存技术,HTTP 设计者早在之前就考虑到了这点,因此 HTTP 协议的头部有不少是针对缓存的字段。
HTTP 缓存有两种实现方式,分别是强制缓存和协商缓存。
HTTP的优点:
简单,易扩展,跨平台性。
缺点:
HTTP是无状态的,也就是说,对于一些网页来说,像是淘宝,我们的每一次请求都要进行用户验证,这样对用户显然是不友好的,所以就有了cookie的出现。
我们先来看第一种情形:我们在网页登录后,若用POST请求,则我们的登录信息则会填写到请求的body中,服务器读到后,会与其数据库中的信息进行校验,成功后才会返回对应的信息,这时我们的浏览器中也会对我们的登录信息进行保存,保存在cookie中,当要继续访问时发送请求时,则填认证信息的过程则由浏览器帮助我们去做了,这样看似方便了,但是是有问题的,当有人在我们的电脑中植入木马,对我们的cookie进行扫描时,我们的信息是不是就泄漏啦。(cookie存储在本地)。那么有什么办法吗?有的!
我们在登录之后不再直接用密码进行验证不就可以了。
当我们的客户端将用户名,密码通过请求发送到服务器上时,在服务器中,会有一个哈希表的东西,其内容是,我们的登录信息和服务器为我们分配的一个session id,这两个值是一一映射的关系,然后服务器将这个id返回给客户端,此时浏览器保存的就是我们的id了,当再要进行验证时,就通过id直接与服务器进行验证。我们的信息也就不会泄露了,但是!仍然是不安全的,因为我们的HTTP是明文传输的,黑客可以通过抓包,从而拿到我们的id从而登录我们的账号。
有什么办法解决吗?有的!HTTPS。
因为http的内容是明⽂传输的,明⽂数据会经过路由器、wifi热点、通信服务运营商、代理服务器等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双⽅察觉,这就是 中间⼈攻击 ,所以我们才需要对信息进⾏加密。
那么它是怎么进行加密的呢?
我们的加密有对称加密和非对称加密。
我们来看一种最接近我们HTTPS加密方式的加密方法。
非对称加密+对称加密
客户端发送连接请求给服务器,服务器发送公钥给客户端,客户端用公钥加密密钥R(R进行的是对称加密)发送给服务器,然后服务器用私钥解密,最后两个主机通过对称密钥R进行通信,但是改方法是有问题的,要是有中间人在开始时就进行攻击,即在向客户端发送公钥时就进行攻击,将公钥换成自己的公钥给客户端,从而就拿到了客户端的密钥R。那么怎么解决呢?本质就是将服务器传给客户端的公钥保护起来。
我们利用CA证书对公钥进行保护。
先是服务端向CA机构申请,CA机构有一把公钥和私钥,其先是用对证书的信息进行哈希,形成摘要,然后对该摘要用私钥加密,形成数字签名,在建立连接时,服务器发送带签名的证书给客户端,该证书中包含服务器的公钥和网站信息,所以要是有中间人进行攻击时,由于其只要对证书的内容进行更改,客户端在收到证书,对其进行哈希形成摘要,再用CA机构的公钥对签名进行解密,若摘要不匹配,则是不合法的,这就避免了上述的中间人攻击的场景。服务器的公钥就得到了保护,然后用该公钥加密客户端的密钥R,给服务器后,两主机就进行对称加密从而通信了。