http协议 订阅
http是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使得开发和部署是那么的直截了当。 [1] 展开全文
http是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使得开发和部署是那么的直截了当。 [1]
信息
外文名
HTTP
适用浏览器
Firefox、Google chrome等
作    用
规定WWW服务器与浏览器之间信息传递规范
中文名
超文本传输协议
工作层
应用层
基    础
架构在TCP协议上
http简介
万维网WWW(world wide web)发源于欧洲日内瓦量子物理实验室CERN,正是WWW技术的出现使得因特网得以超乎想象的速度迅猛发展。这项基于TCP/IP的技术在短短的十年时间内迅速成为已经发展了几十年的Internet上的规模最大的信息系统,它的成功归结于它的简单、实用。在WWW的背后有一系列的协议和标准支持它完成如此宏大的工作,这就是Web协议族,其中就包括HTTP超文本传输协议。 在1990年,HTTP就成为WWW的支撑协议。当时由其创始人WWW之父蒂姆·贝纳斯·李(TimBerners—Lee)提出,随后WWW联盟(WWW Consortium)成立,组织了IETF(Internet Engineering Task Force)小组进一步完善和发布HTTP协议。 [2]  HTTP是应用层协议,同其他应用层协议一样,是为了实现某一类具体应用的协议,并由某一运行在用户空间的应用程序来实现其功能。HTTP是一种协议规范,这种规范记录在文档上,为真正通过HTTP协议进行通信的HTTP的实现程序。HTTP协议是基于C/S架构进行通信的,而HTTP协议的服务器端实现程序有httpd、nginx等,其客户端的实现程序主要是Web浏览器,例如Firefox、InternetExplorer、Google chrome、Safari、Opera等,此外,客户端的命令行工具还有elink、curl等。Web服务是基于TCP的,因此为了能够随时响应客户端的请求,Web服务器需要监听在80/TCP端口。这客户端浏览器和Web服务器之间就可以通过HTTP协议进行通信了。 [3] 
收起全文
精华内容
下载资源
问答
  • http协议
    千次阅读
    2021-08-10 06:38:42

    一、什么是HTTP协议

    HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程。客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一定的通讯格式,HTTP协议用于定义客户端与web服务器通迅的格式。

    二、HTTP协议的版本

    HTTP协议的版本:HTTP/1.0、HTTP/1.1

    HTTP/1.0,发送请求,创建一次连接,获得一个web资源,连接断开。

    HTTP/1.1,发送请求,创建一次连接,获得多个web资源,保持连接。

    三、HTTP组成

    Http协议由Http请求和Http响应组成,当在浏览器中输入网址访问某个网站时, 你的浏览器会将你的请求封装成一个Http请求发送给服务器站点,服务器接收到请 求后会组织响应数据封装成一个Http响应返回给浏览器。即没有请求就没有响应。

    12469242aae5958423ae39e6d1d57f68.png

    0639d1facb9537272c5f872621ca0630.png

    3.2、HTTP——请求行

    请求行中的GET称之为请求方式,常用的有: GET、 POST

    用户如果没有设置,默认情况下浏览器向服务器发送的都是get请求,

    例如在浏览器直接输地址访问,点超链接访问等都是get,用户如想把请求方式改为post,可通过更改表单的提交方式实现。

    不管POST或GET,都用于向服务器请求某个WEB资源,这两种方式的区别主要表现在数据传递上:

    如果请求方式为GET方式,则可以在请求的URL地址后以?的形式带上交给服务器的数据,多个数据之间以&进行分隔,例如:GET /mail/1.html?name=abc&password=xyz HTTP/1.1

    GET方式的特点:在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。

    如果请求方式为POST方式,则可以在请求的实体内容中向服务器发送数据,Post方式的特点:传送的数据量无限制。

    3.3、HTTP——请求头

    HTTP请求中的常用消息头

    accept:浏览器通过这个头告诉服务器,它所支持的数据类型

    Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集

    Accept-Encoding:浏览器通过这个头告诉服务器,支持的压缩格式

    Accept-Language:浏览器通过这个头告诉服务器,它的语言环境

    Host:浏览器通过这个头告诉服务器,想访问哪台主机

    If-Modified-Since: 浏览器通过这个头告诉服务器,缓存数据的时间

    Referer:浏览器通过这个头告诉服务器,客户机是哪个页面来的  防盗链

    Connection:浏览器通过这个头告诉服务器,请求完后是断开链接还是何持链接

    3.4、HTTP--请求体

    当请求方式是post的时,请求体会有请求的参数,格式如下:

    username=zhangsan&password=123

    如果请求方式为get,那么请求参数不会出现在请求体中,会拼接在url地址后面

    http://localhost:8080...?username=zhangsan&password=123

    四、HTTP响应

    0cc437d4faa4de6371468b2fd13559c3.png

    1、响应行:

    Http协议

    状态码:

    常用的状态码如下:

    200 :请求成功。

    302 :请求重定向。(跳转到了其他的页面)

    304 :请求资源没有改变,访问本地缓存。

    404 :请求资源不存在。通常是用户路径编写错误,也可能是服务器资源已删除。

    500 :服务器内部错误。通常程序抛异常(控制台代码错误!)。

    状态信息:状态信息是根据状态码变化而变化的

    2、响应头:

    响应也都是键值对形式,服务器端将信息以键值对的形式返回给客户端。

    3013b7d8c9470eb866c4ecec76eb32c8.png

    3、响应体:

    响应体是服务器回写给客户端的页面正文,浏览器将正文加载到内存,然后解析渲染 显示页面内容

    更多相关内容
  • 应用层协议 ——— HTTP协议

    千次阅读 多人点赞 2022-05-15 20:18:31
    文章目录HTTP协议认识URLurlencode和urldecodeHTTP协议格式HTTP的方法HTTP常见的Header简单的HTTP服务器 HTTP协议 认识URL urlencode和urldecode HTTP协议格式 HTTP的方法 HTTP常见的Header 简单的HTTP服务器

    HTTP协议

    HTTP简介

    HTTP(Hyper Text Transfer Protocol)协议又叫做超文本传输协议,是一个简单的请求-响应协议,HTTP通常运行在TCP之上。

    在编写网络通信代码时,我们可以自己进行协议的定制,但实际有很多优秀的工程师早就已经写出了许多非常成熟的应用层协议,其中最典型的就是HTTP协议。

    认识URL

    URL(Uniform Resource Lacator)叫做统一资源定位符,也就是我们通常所说的网址,是因特网的万维网服务程序上用于指定信息位置的表示方法。

    一个URL大致由如下几部分构成:
    在这里插入图片描述

    一、协议方案名

    http://表示的是协议名称,表示请求时需要使用的协议,通常使用的是HTTP协议或安全协议HTTPS。HTTPS是以安全为目标的HTTP通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。

    常见的应用层协议:

    • DNS(Domain Name System)协议:域名系统。
    • FTP(File Transfer Protocol)协议:文件传输协议。
    • TELNET(Telnet)协议:远程终端协议。
    • HTTP(Hyper Text Transfer Protocol)协议:超文本传输协议。
    • HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer)协议:安全数据传输协议。
    • SMTP(Simple Mail Transfer Protocol)协议:电子邮件传输协议。
    • POP3(Post Office Protocol - Version 3)协议:邮件读取协议。
    • SNMP(Simple Network Management Protocol)协议:简单网络管理协议。
    • TFTP(Trivial File Transfer Protocol)协议:简单文件传输协议。

    二、登录信息

    usr:pass表示的是登录认证信息,包括登录用户的用户名和密码。虽然登录认证信息可以在URL中体现出来,但绝大多数URL的这个字段都是被省略的,因为登录信息可以通过其他方案交付给服务器。

    三、服务器地址

    www.example.jp表示的是服务器地址,也叫做域名,比如www.alibaba.comwww.qq.comwww.baidu.com

    需要注意的是,我们用IP地址标识公网内的一台主机,但IP地址本身并不适合给用户看。比如说我们可以通过ping命令,分别获得www.baidu.comwww.qq.com这两个域名解析后的IP地址。
    在这里插入图片描述
    如果用户看到的是这两个IP地址,那么用户在访问这个网站之前并不知道这两个网站到底是干什么的,但如果用户看到的是www.baidu.comwww.qq.com这两个域名,那么用户至少知道这两个网站分别对应的是哪家公司,因此域名具有更好的自描述性。

    实际我们可以认为域名和IP地址是等价的,在计算机当中使用的时候既可以使用域名,也可以使用IP地址。但URL呈现出来是可以让用户看到的,因此URL当中是以域名的形式表示服务器地址的。

    四、服务器端口号

    80表示的是服务器端口号。HTTP协议和套接字编程一样都是位于应用层的,在进行套接字编程时我们需要给服务器绑定对应的IP和端口,而这里的应用层协议也同样需要有明确的端口号。

    常见协议对应的端口号:

    协议名称对应端口号
    HTTP80
    HTTPS443
    SSH22

    当我们使用某种协议时,该协议实际就是在为我们提供服务,现在这些常用的服务与端口号之间的对应关系都是明确的,所以我们在使用某种协议时实际是不需要指明该协议对应的端口号的,因此在URL当中,服务器的端口号一般也是被省略的。

    五、带层次的文件路径

    /dir/index.htm表示的是要访问的资源所在的路径。访问服务器的目的是获取服务器上的某种资源,通过前面的域名和端口已经能够找到对应的服务器进程了,此时要做的就是指明该资源所在的路径。

    比如我们打开浏览器输入百度的域名后,此时浏览器就帮我们获取到了百度的首页。
    在这里插入图片描述
    当我们发起网页请求时,本质是获得了这样的一张网页信息,然后浏览器对这张网页信息进行解释,最后就呈现出了对应的网页。
    在这里插入图片描述
    我们可以将这种资源称为网页资源,此外我们还会向服务器请求视频、音频、网页、图片等资源。HTTP之所以叫做超文本传输协议,而不叫做文本传输协议,就是因为有很多资源实际并不是普通的文本资源。

    因此在URL当中就有这样一个字段,用于表示要访问的资源所在的路径。此外我们可以看到,这里的路径分隔符是/,而不是\,这也就证明了实际很多服务都是部署在Linux上的。

    六、查询字符串

    uid=1表示的是请求时提供的额外的参数,这些参数是以键值对的形式,通过&符号分隔开的。

    比如我们在百度上面搜索HTTP,此时可以看到URL中有很多参数,而在这众多的参数当中有一个参数wd(word),表示的就是我们搜索时的搜索关键字wd=HTTP
    在这里插入图片描述
    因此双方在进行网络通信时,是能够通过URL进行用户数据传送的。

    七、片段标识符

    ch1表示的是片段标识符,是对资源的部分补充。

    比如我们在看组图的时候,URL当中就会出现片段标识符。
    在这里插入图片描述
    当我们在翻看组图时,这个片段标识符就会发生变化。
    在这里插入图片描述

    urlencode和urldecode

    如果在搜索关键字当中出现了像/?:这样的字符,由于这些字符已经被URL当作特殊意义理解了,因此URL在呈现时会对这些特殊字符进行转义。

    转义的规则如下:

    • 将需要转码的字符转为十六进制,然后从右到左,取4位(不足4位直接处理),每两位做一位,前面加上%,编码成%XY格式。

    示例

    比如当我们搜索C++时,由于+加号在URL当中也是特殊符号,而+字符转为十六进制后的值就是0x2B,因此一个+就会被编码成一个%2B
    在这里插入图片描述
    说明一下: URL当中除了会对这些特殊符号做编码,对中文也会进行编码。

    在线编码工具

    这里分享一个在线编码工具:

    选中其中的URL编码/解码模式,在输入C++后点击编码就能得到编码后的结果。
    在这里插入图片描述
    再点击解码就能得到原来输入的C++。
    在这里插入图片描述
    实际当服务器拿到对应的URL后,也需要对编码后的参数进行解码,此时服务器才能拿到你想要传递的参数,解码实际就是编码的逆过程。

    HTTP协议格式

    应用层常见的协议有HTTP和HTTPS,传输层常见的协议有TCP,网络层常见的协议是IP,数据链路层对应就是MAC帧了。其中下三层是由操作系统或者驱动帮我们完成的,它们主要负责的是通信细节。如果应用层不考虑下三层,在应用层自己的心目当中,它就可以认为自己是在和对方的应用层在直接进行数据交互。
    在这里插入图片描述
    下三层负责的是通信细节,而应用层负责的是如何使用传输过来的数据,两台主机在进行通信的时候,应用层的数据能够成功交给对端应用层,因为网络协议栈的下三层已经负责完成了这样的通信细节,而如何使用传输过来的数据就需要我们去定制协议,这里最典型的就是HTTP协议。

    HTTP是基于请求和响应的应用层服务,作为客户端,你可以向服务器发起request,服务器收到这个request后,会对这个request做数据分析,得出你想要访问什么资源,然后服务器再构建response,完成这一次HTTP的请求。这种基于request&response这样的工作方式,我们称之为cs或bs模式,其中c表示client,s表示server,b表示browser。

    由于HTTP是基于请求和响应的应用层访问,因此我们必须要知道HTTP对应的请求格式和响应格式,这就是学习HTTP的重点。

    HTTP请求协议格式

    HTTP请求协议格式如下:
    在这里插入图片描述
    HTTP请求由以下四部分组成:

    • 请求行:[请求方法]+[url]+[http版本]
    • 请求报头:请求的属性,这些属性都是以key: value的形式按行陈列的。
    • 空行:遇到空行表示请求报头结束。
    • 请求正文:请求正文允许为空字符串,如果请求正文存在,则在请求报头中会有一个Content-Length属性来标识请求正文的长度。

    其中,前面三部分是一般是HTTP协议自带的,是由HTTP协议自行设置的,而请求正文一般是用户的相关信息或数据,如果用户在请求时没有信息要上传给服务器,此时请求正文就为空字符串。

    如何将HTTP请求的报头与有效载荷进行分离?

    当应用层收到一个HTTP请求时,它必须想办法将HTTP的报头与有效载荷进行分离。对于HTTP请求来讲,这里的请求行和请求报头就是HTTP的报头信息,而这里的请求正文实际就是HTTP的有效载荷。

    我们可以根据HTTP请求当中的空行来进行分离,当服务器收到一个HTTP请求后,就可以按行进行读取,如果读取到空行则说明已经将报头读取完毕,实际HTTP请求当中的空行就是用来分离报头和有效载荷的。

    如果将HTTP请求想象成一个大的线性结构,此时每行的内容都是用\n隔开的,因此在读取过程中,如果连续读取到了两个\n,就说明已经将报头读取完毕了,后面剩下的就是有效载荷了。

    获取浏览器的HTTP请求

    在网络协议栈中,应用层的下一层叫做传输层,而HTTP协议底层通常使用的传输层协议是TCP协议,因此我们可以用套接字编写一个TCP服务器,然后启动浏览器访问我们的这个服务器。

    由于我们的服务器是直接用TCP套接字读取浏览器发来的HTTP请求,此时在服务端没有应用层对这个HTTP请求进行过任何解析,因此我们可以直接将浏览器发来的HTTP请求进行打印输出,此时就能看到HTTP请求的基本构成。
    在这里插入图片描述
    因此下面我们编写一个简单的TCP服务器,这个服务器要做的就是把浏览器发来的HTTP请求进行打印即可。

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstring>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    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;
    			
    			close(sock);
    			exit(0);
    		}
    		//爷爷进程
    		close(sock);
    		waitpid(-1, nullptr, 0); //等待爸爸进程
    	}
    	return 0;
    }
    

    运行服务器程序后,然后用浏览器进行访问,此时我们的服务器就会收到浏览器发来的HTTP请求,并将收到的HTTP请求进行打印输出。
    在这里插入图片描述
    说明一下:

    • 浏览器向我们的服务器发起HTTP请求后,因为我们的服务器没有对进行响应,此时浏览器就会认为服务器没有收到,然后再不断发起新的HTTP请求,因此虽然我们只用浏览器访问了一次,但会受到多次HTTP请求。
    • 由于浏览器发起请求时默认用的就是HTTP协议,因此我们在浏览器的url框当中输入网址时可以不用指明HTTP协议。
    • url当中的/不能称之为我们云服务器上根目录,这个/表示的是web根目录,这个web根目录可以是你的机器上的任何一个目录,这个是可以自己指定的,不一定就是Linux的根目录。

    其中请求行当中的url一般是不携带域名以及端口号的,因为在请求报头中的Host字段当中会进行指明,请求行当中的url表示你要访问这个服务器上的哪一路径下的资源。如果浏览器在访问我们的服务器时指明要访问的资源路径,那么此时浏览器发起的HTTP请求当中的url也会跟着变成该路径。
    在这里插入图片描述
    而请求报头当中全部都是以key: value形式按行陈列的各种请求属性,请求属性陈列完后紧接着的就是一个空行,空行后的就是本次HTTP请求的请求正文,此时请求正文为空字符串,因此这里有两个空行。

    HTTP响应协议格式

    HTTP响应协议格式如下:
    在这里插入图片描述
    HTTP响应由以下四部分组成:

    • 状态行:[http版本]+[状态码]+[状态码描述]
    • 响应报头:响应的属性,这些属性都是以key: value的形式按行陈列的。
    • 空行:遇到空行表示响应报头结束。
    • 响应正文:响应正文允许为空字符串,如果响应正文存在,则响应报头中会有一个Content-Length属性来标识响应正文的长度。比如服务器返回了一个html页面,那么这个html页面的内容就是在响应正文当中的。

    如何将HTTP响应的报头与有效载荷进行分离?

    对于HTTP响应来讲,这里的状态行和响应报头就是HTTP的报头信息,而这里的响应正文实际就是HTTP的有效载荷。与HTTP请求相同,当应用层收到一个HTTP响应时,也是根据HTTP响应当中的空行来分离报头和有效载荷的。当客户端收到一个HTTP响应后,就可以按行进行读取,如果读取到空行则说明报头已经读取完毕。

    构建HTTP响应给浏览器

    服务器读取到客户端发来的HTTP请求后,需要对这个HTTP请求进行各种数据分析,然后构建成对应的HTTP响应发回给客户端。而我们的服务器连接到客户端后,实际就只读取了客户端发来的HTTP请求就将连接断开了。

    接下来我们可以构建一个HTTP请求给浏览器,鉴于现在还没有办法分析浏览器发来的HTTP请求,这里我们可以给浏览器返回一个固定的HTTP响应。我们就将当前服务程序所在的路径作为我们的web根目录,我们可以在该目录下创建一个html文件,然后编写一个简单的html作为当前服务器的首页。
    在这里插入图片描述
    当浏览器向服务器发起HTTP请求时,不管浏览器发来的是什么请求,我们都将这个网页响应给浏览器,此时这个html文件的内容就应该放在响应正文当中,我们只需读取该文件当中的内容,然后将其作为响应正文即可。

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstring>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    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;
    			
    #define PAGE "index.html" //网站首页
    			//读取index.html文件
    			ifstream in(PAGE);
    			if (in.is_open()){
    				in.seekg(0, in.end);
    				int len = in.tellg();
    				in.seekg(0, in.beg);
    				char* file = new char[len];
    				in.read(file, len);
    				in.close();
    				
    				//构建HTTP响应
    				string status_line = "http/1.1 200 OK\n"; //状态行
    				string response_header = "Content-Length: " + to_string(len) + "\n"; //响应报头
    				string blank = "\n"; //空行
    				string response_text = file; //响应正文
    				string response = status_line + response_header + blank + response_text; //响应报文
    				
    				//响应HTTP请求
    				send(sock, response.c_str(), response.size(), 0);
    
    				delete[] file;
    			}
    			close(sock);
    			exit(0);
    		}
    		//爷爷进程
    		close(sock);
    		waitpid(-1, nullptr, 0); //等待爸爸进程
    	}
    	return 0;
    }
    

    因此当浏览器访问我们的服务器时,服务器会将这个index.html文件响应给浏览器,而该html文件被浏览器解释后就会显示出相应的内容。
    在这里插入图片描述
    此外,我们也可以通过telnet命令来访问我们的服务器,此时也是能够得到这个HTTP响应的。
    在这里插入图片描述
    说明一下:

    • 实际我们在进行网络请求的时候,如果不指明请求资源的路径,此时默认你想访问的就是目标网站的首页,也就是web根目录下的index.html文件。
    • 由于只是作为示例,我们在构建HTTP响应时,在响应报头当中只添加了一个属性信息Content-Length,表示响应正文的长度,实际HTTP响应报头当中的属性信息还有很多。

    HTTP为什么要交互版本?

    HTTP请求当中的请求行和HTTP响应当中的状态行,当中都包含了http的版本信息。其中HTTP请求是由客户端发的,因此HTTP请求当中表明的是客户端的http版本,而HTTP响应是由服务器发的,因此HTTP响应当中表明的是服务器的http版本。

    客户端和服务器双方在进行通信时会交互双方http版本,主要还是为了兼容性的问题。因为服务器和客户端使用的可能是不同的http版本,为了让不同版本的客户端都能享受到对应的服务,此时就要求通信双方需要进行版本协商。

    客户端在发起HTTP请求时告诉服务器自己所使用的http版本,此时服务器就可以根据客户端使用的http版本,为客户端提供对应的服务,而不至于因为双方使用的http版本不同而导致无法正常通信。因此为了保证良好的兼容性,通信双方需要交互一下各自的版本信息。

    HTTP的方法

    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方法一般用于获取某种资源信息,而POST方法一般用于将数据上传给服务器。但实际我们上传数据时也有可能使用GET方法,比如百度提交数据时实际使用的就是GET方法。

    GET方法和POST方法都可以带参:

    • GET方法是通过url传参的。
    • POST方法是通过正文传参的。

    从GET方法和POST方法的传参形式可以看出,POST方法能传递更多的参数,因为url的长度是有限制的,POST方法通过正文传参就可以携带更多的数据。

    此外,使用POST方法传参更加私密,因为POST方法不会将你的参数回显到url当中,此时也就不会被别人轻易看到。不能说POST方法比GET方法更安全,因为POST方法和GET方法实际都不安全,要做到安全只能通过加密来完成。

    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当中体现出来,而会通过正文将这两个参数传递给了服务器。
    在这里插入图片描述
    此时用户名和密码就通过正文的形式传递给服务器了。
    在这里插入图片描述
    说明一下:

    • 当我们使用GET方法时,我们提交的参数会回显到url当中,因此GET方法一般是处理数据不敏感的。
    • 如果你要传递的数据比较私密的话你一定要用POST方法,倒不是因为POST方法更安全,实际上GET和POST方法传参时都是明文传送,所以都不安全,但是POST方法更私密,因为POST是通过正文传参的,不会将参数立马回显到浏览器的url框当中的,所以相对更私密。

    HTTP的状态码

    HTTP的状态码如下:

    类别原因短语
    1XXInformational(信息性状态码)接收的请求正在处理
    2XXSuccess(成功状态码)请求正常处理完毕
    3XXRedirection(重定向状态码)需要进行附加操作以完成请求
    4XXClient Error(客户端错误状态码)服务器无法处理请求
    5XXServer Error(服务器错误状态码)服务器处理请求出错

    最常见的状态码,比如200(OK),404(Not Found),403(Forbidden请求权限不够),302(Redirect),504(Bad Gateway)。

    Redirection(重定向状态码)

    重定向就是通过各种方法将各种网络请求重新定个方向转到其它位置,此时这个服务器相当于提供了一个引路的服务。

    重定向又可分为临时重定向和永久重定向,其中状态码301表示的就是永久重定向,而状态码302和307表示的是临时重定向。

    临时重定向和永久重定向本质是影响客户端的标签,决定客户端是否需要更新目标地址。如果某个网站是永久重定向,那么第一次访问该网站时由浏览器帮你进行重定向,但后续再访问该网站时就不需要浏览器再进行重定向了,此时你访问的直接就是重定向后的网站。而如果某个网站是临时重定向,那么每次访问该网站时如果需要进行重定向,都需要浏览器来帮我们完成重定向跳转到目标网站。

    临时重定向演示

    进行临时重定向时需要用到Location字段,Location字段是HTTP报头当中的一个属性信息,该字段表明了你所要重定向到的目标网站。

    我们这里要演示临时重定向,可以将HTTP响应当中的状态码改为307,然后跟上对应的状态码描述,此外,还需要在HTTP响应报头当中添加Location字段,这个Location后面跟的就是你需要重定向到的网页,比如我们这里将其设置为CSDN的首页。

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstring>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    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;
    }
    

    此时运行我们的服务器,当我们用telnet命令登录我们的服务器时,向服务器发起HTTP请求时,此时服务器给我们的响应就是状态码307,响应报头当中是Location字段对应的就是CSDN首页的网址
    在这里插入图片描述
    telnet命令实际上只是一来一回,如果我们用浏览器访问我们的服务器,当浏览器收到这个HTTP响应后,还会对这个HTTP响应进行分析,当浏览器识别到状态码是307后就会提取出Location后面的网址,然后继续自动对该网站继续发起请求,此时就完成了页面跳转这样的功能,这样就完成了重定向功能。

    此时当浏览器访问我们的服务器时,就会立马跳转到CSDN的首页。
    在这里插入图片描述

    HTTP常见的Header

    HTTP常见的Header如下:

    • Content-Type:数据类型(text/html等)。
    • Content-Length:正文的长度。
    • Host:客户端告知服务器,所请求的资源是在哪个主机的哪个端口上。
    • User-Agent:声明用户的操作系统和浏览器的版本信息。
    • Referer:当前页面是哪个页面跳转过来的。
    • Location:搭配3XX状态码使用,告诉客户端接下来要去哪里访问。
    • Cookie:用于在客户端存储少量信息,通常用于实现会话(session)的功能。

    Host

    Host字段表明了客户端要访问的服务的IP和端口,比如当浏览器访问我们的服务器时,浏览器发来的HTTP请求当中的Host字段填的就是我们的IP和端口。但客户端不就是要访问服务器吗?为什么客户端还要告诉服务器它要访问的服务对应的IP和端口?

    因为有些服务器实际提供的是一种代理服务,也就是代替客户端向其他服务器发起请求,然后将请求得到的结果再返回给客户端。在这种情况下客户端就必须告诉代理服务器它要访问的服务对应的IP和端口,此时Host提供的信息就有效了。

    User-Agent

    User-Agent代表的是客户端对应的操作系统和浏览器的版本信息。

    比如当我们用电脑下载某些软件时,它会自动向我们展示与我们操作系统相匹配的版本,这实际就是因为我们在向目标网站发起请求的时候,User-Agent字段当中包含了我们的主机信息,此时该网站就会向你推送相匹配的软件版本。在这里插入图片描述

    Referer

    Referer代表的是你当前是从哪一个页面跳转过来的。Referer记录上一个页面的好处一方面是方便回退,另一方面可以知道我们当前页面与上一个页面之间的相关性。

    Keep-Alive(长连接)

    HTTP/1.0是通过request&response的方式来进行请求和响应的,HTTP/1.0常见的工作方式就是客户端和服务器先建立链接,然后客户端发起请求给服务器,服务器再对该请求进行响应,然后立马端口连接。

    但如果一个连接建立后客户端和服务器只进行一次交互,就将连接关闭,就太浪费资源了,因此现在主流的HTTP/1.1是支持长连接的。所谓的长连接就是建立连接后,客户端可以不断的向服务器一次写入多个HTTP请求,而服务器在上层依次读取这些请求就行了,此时一条连接就可以传送大量的请求和响应,这就是长连接。

    如果HTTP请求或响应报头当中的Connect字段对应的值是Keep-Alive,就代表支持长连接。

    Cookie和Session

    HTTP实际上是一种无状态协议,HTTP的每次请求/响应之间是没有任何关系的,但你在使用浏览器的时候发现并不是这样的。

    比如当你登录一次CSDN后,就算你把CSDN网站关了甚至是重启电脑,当你再次打开CSDN网站时,CSDN并没有要求你再次输入账号和密码,这实际上是通过cookie技术实现的,点击浏览器当中锁的标志就可以看到对应网站的各种cookie数据。
    在这里插入图片描述
    这些cookie数据实际都是对应的服务器方写的,如果你将对应的某些cookie删除,那么此时可能就需要你重新进行登录认证了,因为你删除的可能正好就是你登录时所设置的cookie信息。

    cookie是什么呢?

    因为HTTP是一种无状态协议,如果没有cookie的存在,那么每当我们要进行页面请求时都需要重新输入账号和密码进行认证,这样太麻烦了。

    比如你是某个视频网站的VIP,这个网站里面的VIP视频有成百上千个,你每次点击一个视频都要重新进行VIP身份认证。而HTTP不支持记录用户状态,那么我们就需要有一种独立技术来帮我们支持,这种技术目前现在已经内置到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信息通过网络的方式传送给恶意方,当恶意方拿到你的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后的好处

    • 在引入SessionID之前,用户登录的账号信息都是保存在浏览器内部的,此时的账号信息是由客户端去维护的。
    • 而引入SessionID后,用户登录的账号信息是有服务器去维护的,在浏览器内部保存的只是SessionID。

    此时虽然SessionID可能被非法用户盗取,但服务器也可以使用各种各样的策略来保证用户账号的安全。

    • IP是有归类的,可以通过IP地址来判断登录用户所在的地址范围。如果一个账号在短时间内登录地址发送了巨大变化,此时服务器就会立马识别到这个账号发生异常了,进而在服务器当中清除对应的SessionID的值。这时当你或那个非法用户想要访问服务器时,就都需要重新输入账号和密码进行身份认证,而只有你是知道自己的密码的,当你重新认证登录后服务器就可以将另一方识别为非法用户,进而对该非法用户进行对应的黑名单/白名单认证。
    • 当操作者想要进行某些高权限的操作时,会要求操作者再次输入账号和密码信息,再次确认身份。就算你的账号被非法用户盗取了,但非法用户在改你密码时需要输入旧密码,这是非法用户在短时间内无法做到的,因为它并不知道你的密码。这也就是为什么账号被盗后还可以找回来的原因,因为非法用户无法在短时间内修改你的账号密码,此时你就可以通过追回的方式让当前的SessionID失效,让使用该账号的用户进行重新登录认证。
    • SessionID也有过期策略,比如SessionID是一个小时内是有效的。所以即便你的SessionID被非法用户盗取了,也仅仅是在一个小时内有效,而且在功能上受约束,所以不会造成太大的影响。

    任何事情都有两面性,如果不是这些非法用户的存在,现在的服务器肯定是漏洞百出,只有双方不断进行对抗双方才能不断进步。

    实验演示

    当浏览器访问我们的服务器时,如果服务器给浏览器的HTTP响应当中包含Set-Cookie字段,那么当浏览器再次访问服务器时就会携带上这个cookie信息。

    因此我们可以在服务器的响应报头当中添加上一个Set-Cookie字段,看看浏览器第二次发起HTTP请求时是否会带上这个Set-Cookie字段。

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstring>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    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;
    
    #define PAGE "index.html" //网站首页
    			//读取index.html文件
    			ifstream in(PAGE);
    			if (in.is_open()){
    				in.seekg(0, in.end);
    				int len = in.tellg();
    				in.seekg(0, in.beg);
    				char* file = new char[len];
    				in.read(file, len);
    				in.close();
    
    				//构建HTTP响应
    				string status_line = "http/1.1 200 OK\n"; //状态行
    				string response_header = "Content-Length: " + to_string(len) + "\n"; //响应报头
    				response_header += "Set-Cookie: 2021dragon\n"; //添加Set-Cookie字段
    				string blank = "\n"; //空行
    				string response_text = file; //响应正文
    				string response = status_line + response_header + blank + response_text; //响应报文
    				
    				//响应HTTP请求
    				send(sock, response.c_str(), response.size(), 0);
    
    				delete[] file;
    			}
    			close(sock);
    			exit(0);
    		}
    		//爷爷进程
    		close(sock);
    		waitpid(-1, nullptr, 0); //等待爸爸进程
    	}
    	return 0;
    }
    

    运行服务器后,用浏览器访问我们的服务器,此时通过Fiddler可以看到我们的服务器发给浏览器的HTTP响应报头当中包含了这个Set-Cookie字段。
    在这里插入图片描述
    同时我们也可以在浏览器当中看到这个cookie,这个cookie的值就是我们设置的2021dragon,此时浏览器当中就写入了这样的一个cookie。
    在这里插入图片描述
    然后我们输入用户名和密码并提交,此时相当于第二次访问我们的服务器,此时通过Fiddler可以看到,由于我们提交表单参数用的是POST方法,因此这里的参数是通过正文的形式提交的,更重要的是第二次的HTTP请求当中会携带上这个cookie信息。
    在这里插入图片描述

    科普HTTPS协议

    HTTPS VS HTTP

    早期很多公司刚起步的时候,使用的应用层协议都是HTTP,而HTTP无论是用GET方法还是POST方法传参,都是没有经过任何加密的,因此早期很多的信息都是可以通过抓包工具抓到的。

    为了解决这个问题,于是出现了HTTPS协议,HTTPS实际就是在应用层和传输层协议之间加了一层加密层(SSL&TLS),这层加密层本身也是属于应用层的,它会对用户的个人信息进行各种程度的加密。HTTPS在交付数据时先把数据交给加密层,由加密层对数据加密后再交给传输层。

    当然,通信双方使用的应用层协议必须是一样的,因此对端的应用层也必须使用HTTPS,当对端的传输层收到数据后,会先将数据交给加密层,由加密层对数据进行解密后再将数据交给应用层。
    在这里插入图片描述
    此时数据只有在用户层(应用层)是没有被加密的,而在应用层往下以及网络当中都是加密的,这就叫做HTTPS。

    对称加密 VS 非对称加密

    加密的方式可以分为对称加密和非对称加密:

    • 采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密。
    • 采用公钥和私钥来进行加密和解密,用其中一个密钥进行加密就必须用另一个密钥进行解密,这种加密方法称为非对称加密。

    一般而言,对称加密的效率比非对称加密的效率高。

    对称加密的过程

    对称加密的效率更高,因此双方在进行正常通信时使用的是对称加密。但双方要进行对称加密通信,此时就要去加密方要把密钥给解密方,此时解密方才能对数据进行解密,但加密方把密钥(密钥也是数据)给解密方时也是需要对密钥进行加密的,解密废没法解密就没法拿到密钥,这就变成了鸡生蛋蛋生鸡的问题了。

    这里也不可能让加密方给密钥的时候不进行加密,因为那样全世界都知道这个密钥了,后续加密方的加密也就没有意义了。因此刚开始在进行密钥协商的时候需要用非对称加密。

    对称加密的建立过程如下:

    • 通信双方建立连接的时候,双方就可以把支持的加密算法作协商,协商之后在服务器端形成非对称加密时使用的公钥和私钥,在客户端形成对称加密时使用的密钥。
    • 然后服务器将公钥交给客户端(这个公钥全世界都可以看到),然后客户端用这个公钥对客户端形成的密钥进行加密,将加密后的密钥发送给服务器,服务器拿到后再用它的私钥进行解密,最终服务器就拿到了客户端的密钥。
    • 这时客户端和服务器都有了这个密钥,并且其他人是不知道的,此时客户端和服务器就可以进行对称加密通信了。

    需要注意的是,这里客户端用公钥加密后的密钥只有服务器能够解密,因为在非对称加密当中,数据用公钥加密就必须用私钥解密,而只有服务器才有私钥,其他人都只有公钥。

    简单理解对称加密

    如果你还想知道更多的非对称加密算法,可以了解一下RSA,这是一个基于因式分解的非对称加密算法。

    下面我们简单理解一下对称加密,对称加密最典型的例子就是异或运算。
    在这里插入图片描述
    我们用A异或B得到一个中间值C,此时如果我们采用C异或B就能重新得到A。在这个过程中,A就相当于通信双方想要交互的数据,B就相当于对称加密当中的密钥,C就相当于被密钥加密后的数据,异或运算实际就是一个简单的对称加密算法。

    展开全文
  • 【计算机网络】HTTP 协议详解

    万次阅读 多人点赞 2022-03-06 16:55:26
    HTTP 协议介绍2. HTTP 协议的工作过程3. Fiddler 抓包工具介绍3.1 抓包工具的使用3.2 抓包结果3.3 抓包工具原理4. HTTP 协议格式总览5. HTTP 请求(Request)5.1 认识 URLURL 基本介绍URL 基本格式URL 参数介绍...

    1. HTTP 协议介绍

    基本介绍:

    • HTTP(Hyper Text Transfer Protocol): 全称超文本传输协议,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

    • HTTP 是一种应用层协议,是基于 TCP/IP 通信协议来传递数据的,其中 HTTP1.0、HTTP1.1、HTTP2.0 均为 TCP 实现,HTTP3.0 基于 UDP 实现。现主流使用 HTTP1.0 和 HTTP3.0

    • 协议: 为了使数据在网络上从源头到达目的,网络通信的参与方必须遵循相同的规则,这套规则称为协议,它最终体现为在网络上传输的数据包的格式

      通俗点讲,协议就是要保证网络通信的双方,能够互相对接上号。就像是两个人传递纸条通过互相指定的暗号,如果发送天亮了,表示可以打游戏了等等

    注意: 当我们访问一些网页时,是显示通过 HTTPS 来进行通信的,并且当下大多数的网页都是通过 HTTPS 来进行通信的,因为 HTTPS 在 HTTP 的基础上做了一个加密的工作。HTTPS 将在本文末尾具体介绍

    2. HTTP 协议的工作过程

    当我们在浏览器输入一个网址,此时浏览器就会给对应的服务器发送一个 HTTP 请求,对应的服务器收到这个请求之后,经过计算处理,就会返回一个 HTTP 响应。并且当我们访问一个网站时,可能涉及不止一次的 HTTP 请求和响应的交互过程

    基础术语:

    • 客户端: 主动发起网络请求的一端
    • 服务器: 被动接收网络请求的一端
    • 请求: 客户端给服务器发送的数据
    • 响应: 服务器给客户端返回的数据

    HTTP 协议的重要特点: 一发一收,一问一答

    image-20220303134211242

    注意: 网络编程中,除了一发一收之外,还有其它的模式

    • 多发一收:例如上传大文件
    • 一发多收:例如看直播时,搜索一个词条可以得到多个视频源
    • 多发多收:例如串流(steam link、moonlight 等等)

    3. Fiddler 抓包工具介绍

    3.1 抓包工具的使用

    当我们访问一个网站时,可能涉及不止一次的 HTTP 请求和响应的交互,为此为了更加清楚的了解我们访问一个网站时 HTTP 请求/协议是怎么交互的,由于 HTTP 是一个文本格式的协议,就可以通过以下两种方式:

    • 方式一: 通过 F12 打开浏览器的开发者工具,点击 Network 标签页,然后刷新页面就行。显示的每一条记录都是一次 HTTP 请求/响应

      这里通过访问搜狗浏览器为例,来进行演示

    • 方式二(推荐): 抓包工具,这里以 Fiddler 为例,它能够直接读取你电脑上网卡的信息,网卡上有什么数据流动,它都能感知到并且显示出来

    Fiddler 下载官网: https://www.telerik.com/fiddler

    Fiddler 使用方式:

    • 打开 Fiddler,然后打开你要访问的网站,访问该网站的 HTTP 请求和响应就会显示在 Fiddler 上

      这里以访问搜狗浏览器为例,来进行演示

      在这里插入图片描述

    • 当我们选择好我们具体要查看的 HTTP/HTTPS 请求和响应时,右上栏就会显示具体的请求报文内容,右下角就会显示具体的响应报文内容(需要点击 Raw 标签来查看详细的数据格式)

    • 请求和响应的详细数据,可以通过右下角的 view in Notepad 键通过记事本打开

    • 为了方便我们抓取我们自己想查看的抓包结果,可以通过 ctrl + a 全选左侧的抓包结果,ctrl + x 删除选中的所有抓包结果,再进行网页的刷新就行

    • 响应的正文往往是被显示在浏览器上,最常见的响应格式就是 html,很多网站返回的 html 是压缩过的(因为压缩之后,网络传输的数据量就变少了,即节省了网络带宽),所以需要进行解压缩 decode

      image-20220303164957690

    注意: 直接安装的 Fiddler 是无法抓取 HTTPS 的请求的,需要按照以下步骤配置以下才能够抓取

    3.2 抓包结果

    接下来我们来抓取搜狗首页的 HTTP 请求,抓取到的结果如下

    完整的 HTTP 请求:

    image-20220303164244715

    完整的 HTTP 响应:

    image-20220303164355097

    3.3 抓包工具原理

    Fiddler 之所以能够获取到这些 HTTP 请求的详细情况,主要是因为此处的 Fiddler 相当于一个”代理“程序

    代理,也可以理解为中介或代购,就比如你想通过中介去租房或者买房,你会将你的需求告诉给中介,中介就会去寻找房源并将找到的结果的详细情况反应给你。

    上述我们通过 Fiddler 来抓取搜狗首页的 HTTP 请求时,首选我们会访问 sogo.con,即把 HTTP 请求发送给 Fiddler,Fiddler 再把请求转发给搜狗的服务器,当搜狗的服务器返回数据时,Fiddler 就会先拿到返回数据,再把数据交给浏览器

    image-20220303171533144

    4. HTTP 协议格式总览

    到这里,我们学习 HTTP 协议的方法已经学会了,那就是使用抓包工具来抓取我们想要的 HTTP 请求。接下来我们将介绍 HTTP 协议的格式,它是学习 HTTP 协议的重头戏!

    我们将上述得到的搜狗页面的请求为例,整体介绍下 HTTP 协议格式

    • HTTP 请求格式:

      image-20220303222646809

    • HTTP 响应格式:

      image-20220303224536778

    注意: 为什么 HTTP 报文中要存在空行呢?

    • 因为 HTTP 协议并没有规定报头部分的键值对有多少个,使用空行就相当于是报文的结束标记或报文和正文之间的分隔符
    • HTTP 在传输层依赖 TCP 协议,TCP 是面向字节流的。如果没有这个空行,就会出现”粘包问题“

    5. HTTP 请求(Request)

    5.1 认识 URL

    URL 基本介绍

    • 平时我们俗称的”网址“,其实就是 URL(Uniform Resource Locator),翻译为统一资源定位符
    • 互连网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它

    URL 基本格式

    • URL 的标准格式如下:

      协议类型:[//服务器地址[:端口号]][/资源层级 UNIX 文件路径]文件名[?查询字符串][#片段标识符]
      
    • URL 的完整格式如下:

      协议类型:[//[访问资源需要的凭证信息@]服务器地址[:端口号]][/资源层级 UNIX 文件路径]文件名[?查询字符串][#片段标识符]
      

    URL 参数介绍

    信息描述可否省略
    协议类型常见的协议类型有 http 和 https,访问 mysql 时的协议类型为 jdbc:mysql可以省略,省略后默认为 http://
    访问资源需要的凭证信息一般就是登录信息(用户名、密码等),但是现在的网站进行认证一般不再通过 URL 进行,故一般省略可以省略
    服务器地址服务器的地址可以时一个 IP 地址,也可以是一个域名(域名会通过 DNS 系统解析成一个具体的 IP 地址,可以使用 ping 域名 来得到该域名的 IP 地址),IP 地址用来描述网络上的一个具体位置,能够用来定位一个具体的主机在 HTML 中可以省略(比如 img、link、script、a 标签的 src 或者 href 属性),省略后表示服务器的 ip 或域名与当前 HTML 所属的 ip 或域名一致
    端口号端口号的主要作用是表示一台计算机中的特定进程所提供的服务,即用来区分一个主机上的不同程序。每个程序在访问网络的时候,都会关联上一个或多个端口号,通过端口号就能区分出当前的请求要给谁。可以被省略,当端口号省略时,浏览器会根据协议类型自动决定使用哪个端口号(如 http 协议默认使用80端口,https 协议默认使用443端口)
    资源层级 UNIX 文件路径表示访问该服务器程序上某个资源的路径可以省略,省略后相当于 /
    文件名表示访问该服务器上的哪个资源(如 html、图片等等)不能省略
    查询字符串查询字符串(query string)本质是一个键值对结构,且键值对之间使用 & 分割,键和值之间使用 = 分割。表示客户端给服务器传递的参数。该参数是 web 开发的一个重要参数,给前后端交互提供了很多可能性。该参数 key 和 value 的取值和个数,完全都是由程序员自己约定,因此可以通过这样的方式来自定制我们需要的信息给服务器可以省略
    片段标识符片段标识符主要用于页面内跳转,例如跳转到当前页面的某个部分、章节等等可以省略

    通过抓包可以我们来看看几个网站的 URL

    • 我的 CSDN 博客首页

      https://blog.csdn.net/weixin_51367845?spm=1010.2135.3001.5343
      
    • 搜狗首页

      https://www.sogou.com/
      
    • QQ 邮箱首页

      https://mail.qq.com/cgi-bin/frame_html? sid=jXYSnAPw1gkphz9d&r=11a219ff7f0405c621f10f04a0cfb41d
      

    我们会发现,上述几个 URL 都并不完整,因为 URL 中的有些参数是可以省略的

    URLencode 介绍

    当我们用搜狗搜索蛋糕时,通过抓包,我们会得到下面这个 URL

    GET https://www.sogou.com/web?query=%E8%9B%8B%E7%B3%95&_asf=www.sogou.com&_ast=&w=01019900&p=40040100&ie=utf8&from=index-nologin&s_from=index&sut=1129&sst0=1646360982664&lkt=0%2C0%2C0&sugsuv=003B56A6DA4C2A82610BB3A8CFD5D583&sugtime=1646360982664 HTTP/1.1
    

    我们会发现 query string 的有些值是 %E8%9B%8B%E7%B3%950%2C0%2C0,通过 urldecode,知道 %E8%9B%8B%E7%B3%95 就是表示蛋糕

    需要 urlencode 的原因:

    • 这是因为像 /?: 等这样的字符,已经被 url 当做特殊意义理解了,因此这些字符不能随意出现。如果某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义,即 urlencode
    • 一个中文字符由 UTF-8 或者 GBK 这样的编码方式构成,虽然在 URL 中没有特殊含义,但是仍然需要进行转义,否则浏览器可能把 UTF-8/GBK 编码中的某个字节当做 URL 中的特殊符号

    转义的规则如下:

    将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成 %XY 格式。

    但是现在网上有很多现成的可以进行转码的工具,因此需要的时候找度娘即可!

    5.2 认识“方法”(method)

    HTTP 中的方法,就是 HTTP 请求报文中的首行的第一个部分。

    原本 HTTP 的设计者,是希望通过不同的方法,来表达不同的语义。但是至今,其实也没有被实现,以下具体的方法具体起到了什么作用,完全看程序员在代码中是如何实现的。

    虽然 HTTP 中的方法很多,但是最常用的就两个 GET 和 POST。以下主要介绍这两个方法

    方法说明适用版本号
    GET获取资源HTTP 1.0、HTTP 1.1
    POST传输实体主体HTTP 1.0、HTTP 1.1
    PUT传输文件HTTP 1.0、HTTP 1.1
    HEAD获得报文首部HTTP 1.0、HTTP 1.1
    DELETE删除文件HTTP 1.0、HTTP 1.1
    OPTIONS访问支持的方法HTTP 1.1
    TRACE追踪路径HTTP 1.1
    CONNECT要求用隧道协议连接代理HTTP 1.1
    LINK建立和资源之间的联系HTTP 1.1
    UNLINE断开连接关系HTTP 1.1

    GET 方法

    基本介绍:

    GET 是最常用的 HTTP 方法,常用于获取服务器上的某个资源。以下几种方式都会触发 GET 方法的请求

    • 在浏览器中直接输入 URL 回车或点击浏览器收藏夹中的链接,此时浏览器就会发送出一个 GET 请求。
    • HTML 中的 link、img、script 等标签的属性中放的 URL,浏览器也会构造出 HTTP GET 请求
    • 使用 Javascript 重点 ajax,也能构造出 HTTP GET 请求
    • 各种编程语言(只要能够访问网络),就都能够构造出 HTTP GER 请求

    GET 请求的特点:

    • 首行里面的第一个部分就是 GET
    • URL 里面的 query string 可以为空,也可以不为空
    • GET 请求的 header 有若干个键值对结构
    • GET 请求的 body 一般是空的

    GET 请求示例: 搜狗首页请求

    在这里插入图片描述

    POST 方法

    基本介绍

    POST 方法也是一种常见的方法,多用于提交用户输入的数据给服务器(如登录页面)。以下几种方法都会触发 POST 方法的请求

    • 通过 HTML 中的 form 标签可以构造 POST 请求
    • 使用 JavaScript 的 ajax 可以构造 POST 请求

    POST 请求的特点:

    • 首行第一个部分就是 POST
    • URL 里面的 query string 一般是空的
    • POST 请求的 header 里面有若干个键值对
    • POST 请求的 body 一般不为空(body 的具体数据格式,由 header 中的 Content-Type 来描述;body 的具体数据长度,由 header 中的 Content-Length 来描述

    POST 请求示例: QQ 邮箱登录请求

    在这里插入图片描述

    GET 和 POST 的区别

    其实 GET 和 POST 的区别是一个经典的面试题,以下为大家介绍如何在面试中回答上述问题

    答题模板:

    GET 和 POST 其实没有本质区别,使用 GET 的场景完全可以使用 POST 代替,使用 POST 的场景一样可以使用 GET 代替。但是在具体的使用上,还是存在一些细节的区别

    • GET 习惯上会把客户端的数据通过 query string 来传输(body 部分是空的);POST 习惯上会把客户端的数据通过 body 来传输(query string 部分是空的)
    • GET 习惯上用于从服务器获取数据;POST 习惯上是客户端给服务器提交数据
    • 一般情况,程序员会把 GET 请求的处理,实现成“幂等”的;对于 POST 请求的处理,不要求实现成“幂等”
    • GET 请求可以被缓存,可以被浏览器保存到收藏夹中;POST 请求不能被缓存

    补充: 幂等是什么?

    • 一个 HTTP 方法是幂等的,指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说,幂等的方法不应该具有副作用。

      比如我们去抢购一件物品,如果我们已经抢到了要进行下单,由于很多人都在抢购,所以下单后,我们发现好像没有什么反应,因此我们又不断的点机下单。如果最终我们只需要付一件产品的钱,就是幂等的,如果要支付N件产品的钱,就不是幂等的

    • 在正确的条件下,GET、HEAD、PUT 和 DELETE 等方法是幂等的;POST 方法不是幂等的

    • 幂等性只与后端服务器的实际状态有关,而每一次请求接收到的状态码不一定相同

    关于 GET 请求的 URL 长度问题的误解

    • 网上有一种错误的解释: GET 请求的长度是存在上限的,这个上限有被说成 1024kb、2048kb 等等,并且 GET 请求存在上限的原因是 URL 的长度存在上限
    • RFC 2616 标准正确的解释: HTTP 协议由 RFC 2616 标准定义,该标准中明确说明 "Hypertext Transfer Protocol -- HTTP/1.1," does not specify any requirement for URL length,即没有对 URL 的长度有任何限制
    • URL 的长度取决因素: 实际上 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现。在浏览器端,不同的浏览器最大的长度是不同的,但是现在浏览器支持的长度一般都很长;在服务器端,一般这个长度是可以配置的

    关于 POST 比 GET 更安全的误解

    • 网上有一种错误的解释: 如果实现登录页面,如果使用 GET 实现登录,GET 习惯上把数据放到 query string 中,此时就能看到浏览器的 URL 中显示当前的用户名和密码了,所以就并不安全;而 POST 习惯上会把数据放到 body 中,因此登录时就不能直接看到用户名和密码,就安全
    • 正确的理解: 安全问题取决于是否加密以及加密算法的强度。这和将数据信息放到 query string 或 body 中无关,因为通过抓包,我们就可以得到这两部分的数据

    关于 GET 只能传输文本数据的误解

    • 网上有一种错误的解释: GET 只能传输文本数据;POST 可以传输文本数据,也可以传输二进制数据
    • 正确的理解: GET 也可以传输二进制数据,虽然不能直接在 query string 中传输二进制数据,但是可以针对二进制数据进行 urlencode,转码后就可以放到 url 中;GET 还可以直接将二进制数据放到 body 中

    其它方法

    • PUT: 与 POST 相似,但是具有幂等特性,一般用于更新
    • DELETE: 删除服务器指定资源
    • OPTIONS: 返回服务器所支持的请求方法
    • HEAD: 与 GET 类似,只不过响应体不返回,只返回响应头
    • TRACE: 能显示服务器端收到的请求,测试的时候会用到
    • CONNECT: 预留,暂无使用

    上述方法的 HTTP 请求可以使用 ajax 或第三方工具来构造,也能使用可以网络编程的语言来构造

    5.3 认识请求“报头”(header)

    header 的整体格式是键值对结构,每个键值对占一行,键和值之间使用 冒号+空格 进行分割

    以下介绍几个常见的报头

    Host

    HOST 的值表示服务器主机的地址和端口(地址可以是域名,也可以是 IP;端口号可以省略或者手动指定)

    Content-Length

    Content-Length 表示 body 的数据长度,长度单位是字节

    Content-Type

    Content-Type 表示 body 的数据格式,以下介绍三种请求中的数据格式

    • application/x-www-form-urlencoded

      这是 form 表单提交的数据格式,此时 body 的格式就类似于 query string(是键值对的结构,键值对之间使用 & 分割,键与值之间使用 = 分割

    • multipart/form-data

      这是 form 表单提交的数据格式(需要在 from 标签上加上 enctyped="multipart/form-data"),通常用于 HTML 提交图片或者文件

    • application/json

      此时 body 数据为 json 格式,json 格式就是源自 js 的对象的格式。用一个 { } 括住,里面有多个键值对,键值对之间使用逗号分割,键和值之间使用冒号分割

    User-Agent(简称 UA)

    User-Agent 表示浏览器或者操作系统的属性,形如

    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/91.0.4472.77 Safari/537.36
    
    • Windows NT 10.0; Win64; x64 表示操作系统信息
    • AppleWebKit/537.36 (KHTML, like Gecko)Chrome/91.0.4472.77 Safari/537.36 表示浏览器信息

    UA 在早年是一个非常有用的字段,网站的开发者可以根据它来检测页面的“兼容性”

    Referer

    Referer 表示这个页面是从哪个页面跳转过来的,这是一个很有用的字段

    假设我用 bing 浏览器搜索蛋糕,会发现有的搜索结果带有广告字眼,这就相当于广告主在 bing 浏览器用来引流的,当该网站的点击次数越多,用户的成交量也就会上升,金主给浏览器的广告费也就增多。为了统计该广告在某一浏览器的点击次数,就可以通过 Referer 字段来查看。

    我们可以对该 HTTP 请求进行抓包,其中 Referer 字段的值就是 bing 浏览器,即表面该网页是从 bing 浏览器跳转过来的

    image-20220305015207221

    注意: 如果直接在浏览器中输入 URL 或直接通过收藏夹访问页面时,是没有 Referer 的

    Cookie

    Cookie 是什么?

    Cookie 是浏览器提供的一种让程序员在本地存储数据的能力

    为什么需要 Cookie?

    如果没有 Cookie,直接将要存储的数据保存在客户端浏览器所在的主机的硬盘上,那么就会出现很大的安全风险,比如当你不小心打开某个不安全的网站,该网站就可以在你的硬盘上写一个病毒程序,那么你的电脑就挂了!因此浏览器为了保证安全性,就禁止网页中的代码访问主机的硬盘(无法在 JS 中读写文件),因此也就失去了持久化存储的能力,故 Cookie 就很重要!

    Cookie 里面存的是什么?

    Cookie 中存储了一个字符串,是键值对结构的,键值对之间使用 ;分割,键和值之间使用 = 分割

    Cookie 来自哪里,如何往 Cookie 中存储数据?

    Cookie 这个数据可能是客户端(网页)自行通过 JS 写入的,也可能来自于服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据

    Cookie 在浏览器这边是按照域名维度来存储的,例如我们打开 CSDN 的首页,点击网址栏左边的一把小锁就能找到 Cookie,我们就可以看到打开这个网页时,系统按照不同域名设置了 Cookie

    在这里插入图片描述

    每一组都是中都存储了 Cookie,我们点开 csdn.net 这组的 Cookie 就能看到具体的数据

    在这里插入图片描述

    通过抓包工具,我们也能得到 Cookie 的数据,可以发现,上述中的键和值都是存在的,例如 uuid_tt_dd

    在这里插入图片描述

    Cookie 要到哪里去?

    Cookie 字段会在后续的请求中,把浏览器本地存储的这些键值对再发送回服务器

    在这里插入图片描述

    Cookie 的一个经典应用就是保持客户端的登录状态

    在这里插入图片描述

    Cookie 的缺陷:

    每次请求都要把该域名下所有的 Cookie 通过 HTTP 请求传给服务器,因此 Cookie 的存储容量是有限的

    6. HTTP 响应(Response)

    6.1 认识“状态码”(status code)

    状态码表示访问一个页面的结果(如访问成功、失败,还是其它一些情况等等),它是一个3位的整数,从 1xx、2xx、3xx、4xx、5xx,分为五个大类,每个大类的含义都不同。以下介绍一些常见的状态码及它的状态码解释

    200 OK

    表示访问成功

    404 Not Found

    表示没有找到资源

    当你发送请求的 URL 在服务器中找不到该资源,就会出现 404

    403 Forbidden

    表示访问被拒绝

    有的页面通常需要用户有一定的权限才能访问,如未登录

    405 Method Not Allowed

    表示访问的服务器不能支持请求中的方法或者不能使用该请求中的方法

    500 Internal Server Error

    表示服务器出现内部错误

    一般是服务器的代码执行过程中遇到了一些特殊的情况,造成服务器崩溃可能会产生这个状态码

    504 Gateway Timeout

    表示当前服务器负载比较大,服务器处理单条请求的时耗很长,就会出现超时情况

    302 Move temporarily

    表示临时重定向

    重定向相当于手机呼号的呼叫转移功能,如果我们换了一个手机号,就可以去办理该呼叫转移业务,使朋友拨打你的旧号码时,自动跳转到新号码

    301 Moved Permanently

    表示永久重定向,当浏览器收到这种响应时,后续的请求都会被自动改成新的地址

    6.2 认识响应“报头”(header)

    响应报头的基本格式和请求报头的格式基本一致,下面介绍下响应报头的 Content-Type 参数

    Content-Type

    Content-Type 表示 body 的数据格式,以下介绍三种响应中的数据格式

    • text/html

      表示数据格式是 HTML

    • text/css

      表示数据格式是 CSS

    • application/javascript

      表示数据各式是 JavaScript

    • application/json

      表示数据格式是 JSON

    7. 通过 form 表单构造 HTTP 请求

    form 是 HTML 中的一个表单标签,可以用于给服务器发送 GET 或者 POST 请求。

    form 的重要参数:

    • action:用来构造 HTTP 请求的 URL 是什么
    • method:用来构造 HTTP 请求的方法(form 只支持 GET 或 POST 方法)

    input 的重要参数在 form 标签中的含义:

    • type:表示输入框的类型(text 表示文本、password 表示密码、submit 表示提交按钮)
    • name:表示构造出的 HTTP 请求的 query string 的 key
    • value:表示 input 标签的值(对于 type 为 submit 类型来说,value 就对应了按钮上显示的文本)
    • input 标签的内容:表示 query string 的 value

    当我们用 form 表单构造好了 HTTP 请求,点击 submit 提交按钮,就可以将请求发送出去

    7.1 发送 GET 请求

    示例代码:

    <form action="http://aaaaa/myPath" method="get">
        <input type="text" name="username">
        <input type="text" name="password">
        <input type="submit" name="提交">
    </form>
    

    在这里插入图片描述

    在构造的页面中,输入数据后,进行提交,我们再通过抓包,查询到了以下结果

    在这里插入图片描述

    7.2 发送 POST 请求

    示例代码:

    <form action="http://aaaaa/myPath" method="post">
        <input type="text" name="username">
        <input type="text" name="password">
        <input type="submit" name="提交">
    </form>
    

    在这里插入图片描述

    在构造的页面中,输入数据后,进行提交,我们再通过抓包,查询到了以下结果

    在这里插入图片描述

    8. 通过 ajax 构造 HTTP 请求

    ajax(Asynchronous Javascript And XML) 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 ajax)如果需要更新内容,必需重载整个网页面。

    这里不使用 JavaScript 中原生的 ajax,而是用第三方库中 jQuery 里面提供的对 ajax 封装好的一个更简便的版本

    注意:

    • 使用 ajax 不仅可以实现 GET 和 POST 方法的请求,也可以实现其它方法的请求
    • 使用 ajax 不能跨域,即访问的域名和构造的域名需要相同(可以跨域的前提是该服务器允许可以跨域)

    如何安装使用 jQuery 第三方库?

    在 Javascript 中安装第三方库,只要在代码中引入对应库的 CDN 链接即可

    • 先搜索 jquery cdn,

      image-20220306145349357

    • 将复制好的链接,粘贴到 script 标签的 src 中即可

      image-20220306145946860

    CDN 是啥?

    CDN 的全称是 Content Delivery Network。即内容分发网络。CDN 是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。

    jQuery 中的重要参数:

    • $:是一个变量名,是 jQuery 中定义的一个对象。jQuery 里面的各种方法都是这个对象的成员
    • ajax:是 jQuery 封装好的 ajax 方法,其参数是一个对象,用来设置 HTTP 请求的一些参数
    • url:ajax 方法中用来设置 HTTP 请求的参数
    • method:ajax 方法中用来设置 HTTP 方法的参数
    • contentType:ajax 方法中用来设置 HTTP body 数据类型的参数
    • data:ajax 方法中用来设置 HTTP body 数据内容的参数
    • status:ajax 方法中用来表示状态码的参数
    • success:是一个回调函数,如果请求成功,响应返回后,浏览器就会自动调用这个参数

    8.1 发送 GET 请求

    示例代码:

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        $.ajax({
        url: 'http://42.192.83.143:8089/AjaxMockServer/info',
        method: 'GET',
        success: function(data, status){
            console.log(data);
            console.log(status);
        }
    });
    </script>
    

    image-20220306163856958

    8.2 发送 POST 请求

    示例代码:

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        $.ajax({
        url: 'http://42.192.83.143:8089/AjaxMockServer/info',
        method: 'POST',
        contentType: 'text/plain',
        data: 'this is body',
        success: function(data, status){
            console.log(data);
            console.log(status);
        }
    });
    </script>
    

    image-20220306164212387

    展开全文
  • HTTP协议简单概述

    千次阅读 2022-03-18 14:43:39
    HTTP协议基础学习,概述

    学习目标

    HTTP 协议概述

    HTTP 请求响应

    HTTP 请求方法

    HTTP 响应方法

    HTTP 消息报文之请求报文

    HTTP 消息报文之响应报文

    HTTP 消息报文之通用报文

    URL

    ​ 我们更熟悉 URL(Uniform Resource Locator,统一资源定位符)。URL 正是使用 Web 浏览器等访问 Web 页面时需要输入的网页地址。比如,下图的 http://hackr.jp/ 就是 URL。

    image-20220305233009217

    使用 http: 或 https: 等协议方案名获取访问资源时要指定协议类型。 不区分字母大小写,最后附一个冒号(:)

    1.HTTP协议的概述

    1.1 http协议用于客户端和服务器之间的通信

    ​ 在两台计算机使用HTTP协议通信时,在一条通信线路上必定有一端是客户端,另一端是服务端

    ​ 服务端和客户端的身份可能会转换,但是从一条信路上说是确定的。

    1.2 通过请求和响应的交换达成通信

    1.2.1 请求方法

    HTTP协议规定,请求从客户端发出,最后服务器端响应请求并返回。

    实例:

    请求

    image-20220307183740949

    分析
    1. GET表示请求访问服务器的类型,称为方法(method)
    2. /index.htm指明了请求的资源对象,也叫做请求的URL(request-URL)。
    3. HTTP/1.1,是HTTP的版本号,用来提示客户端使用HTTP协议功能。

    综合:请求了HTTP服务器上的/index.htm页面

    请求报文的构成
    请求方法
    请求URL
    协议版本
    可选的请求首部字段
    内容实体构成

    image-20220317132824459

    1.2.2 响应

    image-20220317133033482

    分析:

    1. HTTP/1.1表示服务器对应的HTTP版本
    2. 200 ok表示处理结果的状态码(status code)和原因短语(reason-phrase)
    3. Date: Tue, 10 Jul 2012 06:50:15 GMT显示创建响应的日期时间,是首部字段(header field)内的一个属性。
    4. 接着一个空行,之后是资源实体主体(entity body)

    综合:响应成功返回页面:text/html

    响应报文的构成
    协议版本
    状态码(请求或失败的数字代码)
    解释状态码的原因短语
    可选的响应首部字段
    实体主题

    image-20220317135203737

    1.3HTTP是不保存状态的协议

    ​ HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是不做持久化处理。

    ​ HTTP协议每当有新的请求发送时,就会对应新响应产生。

    ​ 协议本身不保留之前一切的请求或响应报文的信息。这是为了尽快的处理特大事务,确保协议可伸缩性。

    1.4 请求URI定位资源

    ​ HTTP协议使用URI定位资源,所以在互联网上任意位置的资源都能访问到。

    1.4.1 指定URI的方式

    完整请求URI

    GET http://hackr.jp/index.htm HTTP/1.1
    

    在首部字段Host中写明网络的域名或IP地址

    GET /index.htm HTTP/1.1
    Host: hackr.jp
    

    如果不是访问特定资源而是对服务器本身发起请求,可以用一个*代替URI

    下面这个例子是查询HTTP服务器支持的HTTP方法种类

    OPTIONS * HTTP/1.1
    

    1.5 HTTP方法

    下面是HTTP/1.1中可以使用的方法。

    GET:获取资源

    ​ 说明:GET方法用来请求访问已被URI识别的资源。指定资源经过服务器解析后返回响应内容。若为文本远洋返回,如果是程序执行输出。

    例子:

    请求:

    GET /index.html HTTP/1.1                                                                        Host: www.hackr.jp
    

    响应:返回 index.html 的页面资源

    请求:

    GET /index.html HTTP/1.1                   
    Host: www.hackr.jp                                                                          
    If-Modified-Since: Thu, 12 Jul 2012 07:30:00 GMT
    

    响应:仅返回2012年7月12日7点30分以后更新过的index.html页面资源。 如果未有内容更新,则以状态码304 Not Modified作为响应返回

    POST:传输实体主体

    说明:

    ​ POST方法用来传输实体主体。

    例子:

    请求:

    POST /submit.cgi HTTP/1.1                                                                       Host: www.hackr.jp                                                                             Content-Length: 1560(1560字节的数据)
    

    响应:返回submit.cgi接收数据的处理结果

    PUT:传输文件

    说明:

    ​ PUT方法用来传输文件。就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。

    ​ 因为HTTP/1.1没有验证机制,所以要配合其他验证机制进行验证

    例子:

    请求:

    PUT /example.html                                                                             HTTP/1.1 Host: www.hackr.jp                                                                     Content-Type: text/html                                                                         Content-Length: 1560(1560字节的数据)
    

    响应:响应返回状态码204 No Content(比如 :该html已存在于服务器上)

    HEAD:获得报文首部

    说明:

    ​ HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性及资源更新的时间日期

    例子:

    请求

    HEAD /index.html                                                                               HTTP/1.1 Host: www.hackr.jp
    

    响应:返回index.html有关的响应首部

    DELETE:删除文件

    说明:

    ​ DELETE方法用来删除文件,是与PUT相反的方法。DELETE方法按请求URI删除指定资源。

    ​ HTTP/1.1的DELETE同样没有验证机制

    例子:

    请求

    DELETE /example.html                                                                           HTTP/1.1 Host: www.hackr.jp
    

    响应:响应返回状态码204 No Content(比如 :该html已从该服务器上删除)

    OPTIONS:询问支持的方法

    说明:

    ​ OPTION方法用来查询针对URI指定资源支持的方法。

    例子:

    请求

    OPTIONS * HTTP/1.1                                                                             Host: www.hackr.jp
    

    响应

    HTTP/1.1 200 OK                                                                                 Allow: GET, POST, HEAD, OPTIONS                                                              (返回服务器支持的方法)
    

    TRACE:追踪路径

    说明:

    ​ TRACE方法是让web服务器端将之前的请求通信环会给客户端的方法。

    ​ 发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个 服务器端就将该数字减 1,当数值刚好减到 0 时,就停止继续传输,最 后接收到请求的服务器端则返回状态码 200 OK 的响应。 客户端通过 TRACE 方法可以查询发送出去的请求是怎样被加工修 改 / 篡改的。这是因为,请求想要连接到源目标服务器可能会通过代理 中转,TRACE 方法就是用来确认连接过程中发生的一系列操作。(容易引发跨站追踪攻击)

    例子:

    请求

    TRACE / HTTP/1.1
    Host: hackr.jp
    Max-Forwards: 2
    

    响应

    HTTP/1.1 200 OK
    Content-Type: message/http
    Content-Length: 1024
    
    TRACE / HTTP/1.1
    Host: hackr.jp 
    Max-Forwards: 2(返回响应包含请求内容)
    

    CONNECT: 要求用隧道协议链接代理

    说明:

    ​ CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL和TLS协议把通信内容加密后经网络隧道传输。

    ​ CONNECT方法的格式如下图所示。

    CONNECT 代理服务器名:端口号 HTTP版本

    例子:

    请求:

    CONNECT proxy.hackr.jp:8080                                                                     HTTP/1.1 Host: proxy.hackr.jp
    

    响应:

    HTTP/1.1 200 OK(之后进入网络隧道)
    

    1.6 使用方法下达命令

    ​ 向请求URI指定的资源发送请求报文时,采用称为方法的命令。

    方法说明支持的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.1
    UNLINE断开连接关系1.1

    LINK和UNLINK已被HTTP/1.1废弃

    1.7持久连接节省通信量

    ​ HTTP协议的初始版本中,没进行一次HTTP通信就要断开一次TCP连接.

    ​ 当年的传输内容都是很小的文本传输,所以不会有问题,随着HTTP的发展web页面中可能包含大量的图片,乃至视频。因此,每次请求都会应为多次断开TCP连接增加通信开销。

    1.7.1 持久连接

    ​ 为了解决TCP连接问题,HTTP/1.1和一部分HTTP/1.0想出了持久连接。HTTP Persistent Connections,也称为 HTTP keep-aliveHTTP connection reuse

    ​ 在 HTTP/1.1 中,所有的连接默认都是持久连接,但在 HTTP/1.0 内 并未标准化。客户端和服务器端都要支持才可以。

    特点:

    ​ 只要任意一端没有明确断开连接,则保持TCP连接状态。需要请求断开。

    优点:

    1. 减少重复建立连接的额外开销,减轻服务器端的负载
    2. 减少开销那部分时间,web页面响应速度提高。

    1.7.2 管线化

    ​ 持久连接使得管线化(pipeliing)成为可能。

    ​ 管线化技术的特点是不用等待响应就可以直接发送下一个请求,这样就可以同时发送多个请求而不需要一个接一个的等待响应了。

    ​ 管线化技术比持久连接还要快,请求数量越多时间差越明显。

    1.8 使用Cookie的状态管理

    ​ HTTP是无状态协议,由于不保存之前的状态和响应所以减少了资源消耗。可如果碰到需要身份验证的web页面岂不是要每一次都要重新验证,所以人们应用了Cokie技术。

    Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端状态。

    ​ Cookie会根据响应报文内一个叫Set-Cookie的首部字段通知客户端保存Cookie。下次发送请求会携带Cookie值发送出去。

    ​ 服务器发现cookie值后,会检查那个客户端发来的请求然会对比服务器的记录找到之前的状态。

    例子:

    1. 请求报文(没有Cookie信息的状态)

    image-20220318142329066

    1. 响应报文(服务器端生成Cookie信息)

    image-20220318142525231

    1. 请求报文(自动发送保存着的Cookie信息)

    image-20220318142631849

    以上就是一次Cookie请求的过程。

    展开全文
  • Http协议详解

    千次阅读 多人点赞 2022-01-20 19:16:54
    超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它是基于 TCP 协议的应用层传输协议。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。 HTTP 是一种无状态 ...
  • HTTP协议的详细介绍

    千次阅读 2022-01-20 22:53:42
    一、何为HTTP协议 1.HTTP协议详细信息 2.HTTPS协议: 3.HTTP协议的特点 二、HTTP协议 请求方式 HTTP1. 0定义了三种请求方法: 1.GET 2.POST 3.HEAD HTTP1. 1 新增了五种请求方法: 1.OPTIONS 2.PUT 3....
  • 第一:HTTP协议

    千次阅读 2022-01-05 10:42:12
    HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的...
  • 详解 —— HTTP协议

    万次阅读 多人点赞 2022-05-12 19:31:11
    1 HTTP协议格式和抓取 我们之前已经讨论过了关于TCP和UDP这两种协议了,而上述的两种协议是属于“二进制协议”,通常需要理解到二进制的bit位(例如TCP中的六位标志位,若代表ACK的那一位为1,则代表这一条为ACK)...
  • http协议格式

    千次阅读 2022-04-11 09:45:03
    HTTP协议格式(http数据结构 / http协议实现):将http通信划分为四个部分: 首行:请求行/响应行—>包含了本次请求与响应的关键描述,请求方法,协议版本,url,处理结果。 头部:关于请求或者响应或者正文的一些...
  • 冰河就趁着周末,只用了几个Java类就简单的实现了Http协议,爽!!
  • HTTP协议解析

    千次阅读 2022-04-17 22:42:10
    一、HTTP协议基础1.定义2.工作原理3、特点4、http与Https的区别。HTTP请求协议——请求方法;Get与POST的区别。HTTP响应协议。 一、HTTP协议基础 1.定义 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)...
  • HTTP协议简介HTTP协议工作原理和流程浏览器在使用HTTP协议时,用户访问网站的流程HTTP协议的请求格式HTTP协议的响应格式状态码重定向的请求代表当前功能还需要后续操作才能完成。 简介 HTTP协议(Hyper Text ...
  • 本篇文章主要介绍了HTTP协议的重要性、什么是协议、什么是HTTP协议HTTP协议的工作流程、HTTP请求信息和响应信息的格式。
  • HTTP协议规范

    千次阅读 2022-03-23 10:06:51
    HTTP协议规范1. HTTP, HTTP/22. 其他HTTP相关协议规范3. IETF网站 1. HTTP, HTTP/2 版本 RFC/链接地址 发布日期 维护者 HTTP 0.9 The Original HTTP as defined in 1991 at W3.org 1991 W3.org HTTP/1.0 ...
  • HTTP协议超级详解

    千次阅读 2021-04-21 21:54:59
    HTTP协议简介 ———————————————————————————————————————— 超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的...
  • HTTP协议详解(超级详细)

    千次阅读 多人点赞 2021-05-14 11:24:00
    HTTP协议格式HTTP请求请求行请求头(Header)空行请求体(Body)HTTP响应状态行响应头(Header)空行响应体(Body)消息头请求头响应头hTTP工作流程 1. HTTP概述 HTTP 协议(Hypertext Transfer Protocol,超文本传输...
  • HTTP协议相关漏洞

    千次阅读 2022-03-22 10:04:02
    一、HTTP协议 HTTP是一个基于请求与响应模式的、无状态的应用层协议。 请求响应   客户端要向web服务器发送一个请求以后,等待服务器回送http响应消息。 无状态   http协议整个过程当中的各种信息不会被服务器所...
  • HTTP协议之:HTTP/1.1和HTTP/2

    万次阅读 2021-08-26 04:35:39
    HTTP的全称是Hypertext Transfer Protocol,是在1989年World Wide Web发展起来之后出现的标准协议,用来在WWW上传输数据。HTTP/1.1是1997年在原始的HTTP协议基础上进行的补充和优化。
  • TCP/IP协议簇之HTTP协议

    千次阅读 2020-09-30 16:06:02
    1.HTTP协议概述及特点 1.1 HTTP协议概述 1.2 HTTP协议特点 2. HTTP报文格式 2.1 HTTP请求报文 2.2HTTP响应报文 3.HTTP请求/响应头参数 3.1 通用请求首部 3.2常用请求头部参数 3.3常用响应头部参数 ...
  • HTTP协议工作原理、工作过程

    千次阅读 2020-06-02 10:35:56
    HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输...
  • 既然有http为何还有RPC HTTP的REST风格的调用: REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络...
  • 什么是Http协议无状态?怎么解决Http无状态

    千次阅读 多人点赞 2021-09-05 19:04:56
    一、Http 协议无状态的含义 1.1有状态协议 常见的许多七层协议实际上是有状态的,例如SMTP协议,它的第一条消息必须是HELO,用来握手,在HELO发送之前其他任何命令都是不能发送的;接下来一般要进行AUTH阶段,用来验证...
  • 即超文本传输协议,网站是基于HTTP协议的,例如网站的图片、CSS、JS等都是基于HTTP协议进行传输的。 HTTP协议是由从客户机到服务器的请求(Request)和从服务器到客户机的响应(Response)进行了约束和规范。 即HTTP...
  • 各种协议HTTP 协议的关系

    千次阅读 2022-04-14 16:14:46
    各种协议HTTP 协议的关系 域名解析:域名变成字符串; 发送HTTP请求,请求报文; TCP协议对请求报文进行分组分割; IP协议负责路由转发(迪杰特斯拉算法); 接收端TCP对分组信息进行重组; 请求返回结果并把...
  • HTTP协议与HTTPS协议详解(含常见面试题)

    千次阅读 多人点赞 2021-02-13 18:16:08
    目录1.HTTP协议1.1HTTP协议是什么1.2 HTTP协议工作过程1.3 HTTP请求方法1.4.HTTP请求报文和应答报文1.5 HTTP状态码2.HTTPS协议2.1.什么是https协议2.2.加密模型2.3.数字证书2.4.HTTPS工作过程3.常见面试题总结3.1.在...
  • http协议与tcp协议区别

    千次阅读 2021-06-15 21:47:51
    http协议与tcp协议区别 1、性质不同: http是一个简单的请求-响应协议。TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。 2、连接不同: TCP连接到不同但互连的计算机通信网络的主计算机中的成对进程之间...
  • 什么是http协议

    千次阅读 多人点赞 2021-02-04 09:14:44
    一,HTTP协议 HTTP协议是超文本传输协议的缩写,是用于从万维网服务器传输超文本到本地浏览器的传送协议。 (超文本是用超链接的方法,将各种不同空间的文字信息组织在一起的网状文本) HTTP是一个基于TCP/IP...
  • http协议及基于http协议的文件下载

    千次阅读 2019-10-11 12:27:41
    5. 基于HTTP协议的文件下载 5.1 文件整体下载 5.2 文件分段(Range)下载 5.2.1 获取文件的大小 5.2.2 下载分段文件 5.3 文件分块(chunk)下载 1. HTTP 协议概述 日常我们使用网络用得最多的无疑是在Web ...
  • 一文搞懂HTTP协议(带图文)

    万次阅读 多人点赞 2020-05-29 22:47:20
    网络是由若干节点和连接这些节点的链路构成,然后网络与网络之间所串连成的庞大网络叫做互联网,而我们今天要讲的HTTP(HyperText Transfer Protocol 超文本传输协议)是互联网上应用最为广泛的一种网络协议,它是由...
  • 面试必考HTTP协议面试题(含答案)

    万次阅读 多人点赞 2022-03-01 23:52:13
    今天我们整理一下关于前端面试时会问到HTTP协议的问题 注:个人观点及答案,望大家采纳,指教!! HTTP 简介: HTTP 协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,426,355
精华内容 570,542
关键字:

http协议

友情链接: 4.zip