HTTP的方法
HTTP的状态码
HTTP常见的Header
Cookie和Session
HTTP VS HTTPS
HTTP/1.1,HTTP/2,HTTP/3演变
前面一章初步认识了URL,HTTP请求和相应协议格式,有所忘记的可以看一下前面的博客
(3条消息) 【网络篇】第十四篇——HTTP协议(一)(附带电视剧李浔同款爱心+端口号被恶意占用如何清除)_接受平凡 努力出众的博客-CSDN博客
HTTP常见的方法有:
方法 | 说明 | 支持的HTTP协议版本 |
GET | 获取资源 | 1.0,1.1 |
POST | 传输实体主体 | 1.0,1.1 |
PUT | 传输文件 | 1.0,1.1 |
HEAD | 获得报文首部 | 1.0,1.1 |
DELETE | 删除文件 | 1.0,1.1 |
OPTIONS | 访问支持的方法 | 1.1 |
TRACE | 追踪路径 | 1.1 |
CONNECT | 要求用隧道协议连接代理 | 1.1 |
LINK | 建立和资源之间的联系 | 1.0 |
UNLINK | 断开连接关系 | 1.0 |
其中最常用的就是GET方法和POST方法。
GET方法和POST方法
GET方法的含义是请求从服务器获取资源, 这个资源可以是文本,页面,图片视频等等。
例如,你打开我在CSDN写的文章,浏览器就会发送GET请求给服务器,服务器就会返回文章的所有文字及资源。
POST方法则是相反的,一般用于将数据上传给服务器,它向URI指定的资源提交数据,数据就放在报文的body中.
例如,你在我的CSDN文章下面,评论了然后提交,浏览器就会执行一次POST请求,把你的评论放进报文body里,然后拼接好POST请求头,通过TCP协议发送给服务器。
GET方法和POST方法都可以带参:
从GET方法和POST方法的传参形式可以看出,POST方法能传递更多的参数,因为url的长度是有限制的,而POST方法通过正文传参就可以携带比它更多的数据。
使用POST方法的传参会更加私密,因为POST方法不会将你的参数回显到url当中,此时也就不会被别人轻易看到。不能说POST方法比GET方法更安全,因为POST方法和GET方法实际上都不安全,要做到安全只能通过加密来完成。
GET和POST方法都是安全和幂等的嘛?
先说明下安全和幂等的概念:
Postman演示GET和POST区别
如果访问我们的服务器使用的是GET方法,此时应该通过url进行传参,可以在Params下进行参数设置,因为Postman当中的Params就相当于url当中的参数,你在设置参数时可以看到对应的url也在随之变化。
此时在我们的服务器收到的HTTP请求当中,可以看到请求行中的url就携带上了我们刚才在Postman当中设置的参数。
而如果我们使用的是POST方法,此时就应该通过正文进行传参,可以在Body下进行参数设置,在设置时可以选中Postman当中的raw方式传参,表示原始传参,也就是你输入的参数是什么样的实际传递的参数就是什么样的.
此时服务器收到的HTTP请求的请求正文就不再是空字符串了,而是我们通过正文传递的参数。
因为此时响应正文不为空字符串,因此响应报头当中出现了Content-Length属性,表示响应正文的长度。
TCP套接字演示GET和POST的区别
要演示GET方法和POST方法传参的区别,就需要让浏览器提交参数,此时我们可以在index.html当中再加入两个表单,用作用户名和密码的输入,然后再新增一个提交按钮,此时就可以让浏览器提交参数了。
我们可以通过修改表单当中的method属性指定参数提交的方法,还有一个属性叫做action,表示想把这个表单提交给服务器上的哪个资源。
此时当我们用浏览器访问我们的服务器时,就会显示这两个表单。
当前我们是用GET方法提交参数的,当我们填充完用户名和密码进行提交时,我们的用户名和密码就会自动被同步到url当中。
同时在服务器这边也通过url收到了刚才我们在浏览器提交的参数。
如果我们将提交表单的方法改为POST方法,此时当我们填充完用户名和密码进行提交时,对应提交的参数就不会在url当中体现出来,而会通过正文将这两个参数传递给了服务器。
此时用户名和密码就通过正文的形式传递给服务器了。
说明一下:
「200 OK]是最常见的成功状态码,表示一切正常。如果是非HEAD请求,服务器返回的响应头都会有body数据。
「204 No Content]也是最常见的成功状态码,也200 OK基本相同,但是响应头没有body数据。
[206 Partial Contentt]:是应用于HTTP分块下载或断点续传,表示响应返回的body数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
301 和 302 都会在响应头里使用字段 Location ,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。 「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,用于缓存控制。
临时重定向演示
进行临时重定向时需要用到Location字段,Location字段是HTTP报头当中的一个属性信息,该字段表明了你所要重定向到的目标网站。
我们这里要演示临时重定向,可以将HTTP响应当中的状态码改为307,然后跟上对应的状态码描述,此外,还需要在HTTP响应报头当中添加Location字段,这个Location后面跟的就是你需要重定向到的网页,比如我们这里将其设置为CSDN的首页。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;int main()
{//创建套接字int listen_sock = socket(AF_INET, SOCK_STREAM, 0);if (listen_sock < 0){cerr << "socket error!" << endl;return 1;}//绑定struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(8081);local.sin_addr.s_addr = htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0){cerr << "bind error!" << endl;return 2;}//监听if (listen(listen_sock, 5) < 0){cerr << "listen error!" << endl;return 3;}//启动服务器struct sockaddr peer;memset(&peer, 0, sizeof(peer));socklen_t len = sizeof(peer);for (;;){int sock = accept(listen_sock, (struct sockaddr*)&peer, &len);if (sock < 0){cerr << "accept error!" << endl;continue;}if (fork() == 0){ //爸爸进程close(listen_sock);if (fork() > 0){ //爸爸进程exit(0);}//孙子进程char buffer[1024];recv(sock, buffer, sizeof(buffer), 0); //读取HTTP请求cout << "--------------------------http request begin--------------------------" << endl;cout << buffer << endl;cout << "---------------------------http request end---------------------------" << endl;//构建HTTP响应string status_line = "http/1.1 307 Temporary Redirect\n"; //状态行string response_header = "Location: https://www.csdn.net/\n"; //响应报头string blank = "\n"; //空行string response = status_line + response_header + blank; //响应报文//响应HTTP请求send(sock, response.c_str(), response.size(), 0);close(sock);exit(0);}//爷爷进程close(sock);waitpid(-1, nullptr, 0); //等待爸爸进程}return 0;
}
如果我们用浏览器访问我们的服务器,当浏览器收到这个HTTP响应后,还会对这个HTTP响应进行分析,当浏览器识别到状态码是307后就会提取出Location后面的网址,然后继续自动对该网站继续发起请求,此时就完成了页面跳转这样的功能,这样就完成了重定向功能。
此时当浏览器访问我们的服务器时,就会立马跳转到CSDN的首页。
HTTP常见的Header如下:
Host:
客户端发送请求时,用来指定服务器的域名。
有了Host字段,就可以将请求发往[同一台]服务器上的不同网站。
Content-Length
服务器在返回数据时,会有Content-Length字段,表明本次回应的数据长度
如上面则是告诉浏览器,本次服务器回应的数据长度是1000个字节,后面的字节就属于下一个回应了。
Connection
Connection 字段最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。
一个可以复用的 TCP 连接就建立了,直到客户端或服务器主动关闭连接。但是,这不是标准字段。
User-Agent
User-Agent代表的是客户端对应的操作系统和浏览器的版本信息。
比如当我们用电脑下载某些软件时,它会自动向我们展示与我们操作系统相匹配的版本,这实际就是因为我们在向目标网站发起请求的时候,User-Agent字段当中包含了我们的主机信息,此时该网站就会向你推送相匹配的软件版本。
Content-Type
Content-Type 字段用于服务器回应时,告诉客户端,本次数据是什么格式。
上面的类型表明,发送的是网页,而且编码是UTF-8.
客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式。 上面代码中,客户端声明自己可以接受任何格式的数据。
Content-Encoding
Content-Encoding 字段说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式 。
HTTP实际上是一种无状态协议,HTTP的每次请求/响应之间是没有任何关系的,但你在使用浏览器的时候发现并不是这样的。
比如你登录一次CSDN侯,就算把CSDN网站关了甚至是重启电脑,当你再次打开CSDN网站时,CSDN并没有要求你再次输入账号和密码,这实际上就是通过cookie技术实现的,点击浏览器当中的锁的标志就可以看到对应网站的各种cookie数据。
这些cookie数据实际都是对应的服务器方写的,如果你将对应的某些cookie删除,那么此时可能就需要你重新进行登录认证了,因为你删除的可能正好就是你登录时所设置的cookie信息。
cookie是什么
由于HTTP是一种无状态协议,如果没有cookie的存在,那么每当要进行页面请求时都需要重新输入账号和密码进行认证,这样太麻烦。
例如登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息。 那么我们就需要有一种独立技术帮助我们支持,这种技术目前已经内置到HTTP协议种,叫做cookie。当我们第一次登录某个网站时,需要输入我们的账号和密码进行身份认证,此时如果服务器经过数据比对后判定你是一个合法的用户,那么为了让你后续在进行某些网页请求时不用重新输入账号和密码,此时服务器就会进行Set-Cookie的设置。(Set-Cookie也是HTTP报头当中的一种属性信息)
当认证通过并在服务端进行Set-Cookie设置后,服务器在对浏览器进行HTTP响应时就会将这个Set-Cookie响应给浏览器。而浏览器收到响应后会自动提取出Set-Cookie的值,将其保存在浏览器的cookie文件当中,此时就相当于我的账号和密码信息保存在本地浏览器的cookie文件当中。
从第一次登录认证之后,浏览器再向该网站发起HTTP请求当中就就会自动包含一个cookie字段,其中携带的就是我第一次的认证信息,此后对端服务器需要对你进行认证时就会直接提取出HTTP请求当中的cookie字段,而不会重新让你输出账号和密码了。
相当于,在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了了也就是在第一次认证登录后,后续所有的认证都变成了自动认证,这就叫做cookie技术。
内存级别&文件级别
cookie就是在浏览器当中的一个小文件,文件里记录就是用户的私有信息,cookie文件可以分种,一种是内存级别的cookie文件,另一种是文件级别的cookie文件。
cookie被盗取
如果你浏览器当中保存的cookie信息被非法用户盗取了,那么此时这个非法用户就可以用你的cookie信息,以你的身份去访问你曾经访问过的网站,我们将这种现象称为cookie被盗取了。
比如你不小心点了某个链接,这个链接可能就是一个下载程序,当你点击之后它就会通过某种方式把程序下载到你本地,并且自动执行该程序,该程序会扫描你的浏览器当中的cookie目录,把所有的cookie信息通过网络的方式传送给恶意方,当恶意方拿到你的cookie信息后就可以拷贝到它的浏览器对应的cookie目录当中,然后以你的身份访问你曾经访问过的网站。
SessionID
单纯的使用cookie是非常不安全的,因为此时cookie文件当中就保存的是你的私密信息,一旦cookie文件泄漏你的隐私信息也就泄漏。
所以当前主流的服务器还引入了SessionID这样的概念,当我们第一次登录某个网站输入账号和密码后,服务器认证成功后还会服务端生成一个对应的SessionID,这个SessionID与用户信息是不相关的。系统会将所有登录用户的SessionID值统一维护起来。
此时当认证通过后服务端在对浏览器进行HTTP响应时,就会将这个生成的SessionID值响应给浏览器。浏览器收到响应后会自动提取出SessionID的值,将其保存在浏览器的cookie文件当中。后续访问该服务器时,对应的HTTP请求当中就会自动携带上这个SessionID
而服务器识别到HTTP请求当中包含了SessionID,就会提取出这个SessionID,然后再到对应的集合当中进行对比,对比成功就说明这个用户是曾经登录过的,此时也就自动就认证成功了,然后就会正常处理你发来的请求,这就是我们当前主流的工作方式。
安全是相对的
引入SessionID之后,浏览器当中的cookie文件保存的是SessionID,此时这个cookie文件同样可能被盗取。此时用户的账号和密码虽然不会泄漏了,但用户对应的SessionID是会泄漏的,非法用户仍然可以盗取我的SessionID去访问我曾经访问过的服务器,相当于还是存在刚才的问题。
这种方法虽然没有真正解决安全问题,但这种方法是相对安全的。互联网上是不存在绝对安全这样的概念的,任何安全都是相对的,就算你将发送到网络当中的信息进行加密,也有可能被别人破解。
不过在安全领域有一个准则:如果破解某个信息的成本已经远远大于破解之后获得的收益(说明做这个事是赔本的),那么就可以说这个信息是安全的
引入SessionID后的好处
此时虽然SessionID可能被非法用户盗取,但服务器也可以使用各种各样的策略来保证用户账号的安全。
任何事情都有两面性,如果不是这些非法用户的存在,现在的服务器肯定是漏洞百出,只有双方不断进行对抗双方才能不断进步。
HTTP与HTTPS有哪些区别?
1.HTTP是超文本传输协议,信息是明文传输,存在安全风险的问题,HTTPS则解决HTTP不安全的缺陷,在TCP和HTTP网络层之间加入了SSL/TLS安全协议,使得报文能够加密传输。
2. HTTP连接建立相对简单,TCP三次握手后便可以进行HTTP的报文传输。而HTTPS在TCP三次握手之后,还需进行SSL/TLS的握手过程,才可进入加密报文传输。
3.HTTP的端口号是80,HTTPS的端口号是443。
4.HTTPS协议需要向CA申请数字整数,来保证服务器的身份是可信的。
HTTPS解决了HTTP的哪些问题?
HTTP由于是明文传输,所以安全上存在以下三个风险:
HTTPS在HTTP与TCP层之间加入了SSL/TLS协议,可以很好的解决了上述的风险:
可见,SSL/TLS协议是能保证通信是安全的.
HTTPS是如何解决上面的三个风险的?
混合加密
通过混合加密的方式就可以保证信息的机密性,解决了窃听的风险.
采用「混合加密」的方式的原因:
摘要算法
摘要算法用来实现完整性,能够为数据生成独一无二的「指纹」,用于校验数据的完整性,解决了篡改的风险。客户端在发送明文之前会通过摘要算法算出明文的「指纹」,发送的时候把「指纹 + 明文」一同加密成密文后,发送给服务器,服务器解密后,用相同的摘要算法算出发送过来的明文,通过比较客户端携带的「指纹」和当前算出的「指纹」做比较,若「指纹」相同,说明数据是完整的。 数字证书 客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。 这就存在些问题,如何保证公钥不被篡改和信任度? 所以这里就需要借助第三方权威机构 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。
HTTP/1.1相比 HTTP/1.0提高了什么性能?
HTTP/1.1相比HTTP/1.0性能上的改进:
但HTTP/1.1还是有性能瓶颈:
HTTP/2 协议是基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的。 那 HTTP/2 相比 HTTP/1.1 性能上的改进: 1. 头部压缩 HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会 帮你消除重复的部分。 这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表, 生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。 2. 二进制格式 HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(frame):头信息帧和数据帧。 这样虽然对人不友好,但是对计算机非常友好,因为计算机只懂二进制,那么收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率。 3. 数据流 HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。 每个请求或回应的所有数据包,称为一个数据流( Stream )。每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求。 4. 多路复用 HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应。 移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟, 大幅度提高了连接的利用率。 举例来说,在一个 TCP 连接里,服务器收到了客户端 A 和 B 的两个请求,如果发现 A 处理过程非常耗 时,于是就回应 A 请求已经处理好的部分,接着回应 B 请求,完成后,再回应 A 请求剩下的部分。 5. 服务器推送 HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式,服务不再是被动地响应,也可以主动向客户端发送消息。 举例来说,在浏览器刚请求 HTML 的时候,就提前把可能会用到的 JS、CSS 文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫 Cache Push)。那上面的HTTP/1.1的性能瓶颈,HTTP/2做了什么优化?
HTTP/2 主要的问题在于,多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的。所以一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。HTTP/2有哪些缺陷?HTTP/3做了哪些优化?
QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,这样会出现新的问题。所以 HTTP/3 现在普及的进度非常的缓慢,不知道未来 UDP 是否能够逆袭 TCP。