1. 什么是HTTP协议
HTTP是应用层的协议。Java最主要的应用场景是做网站,而网站由 后端(HTTP服务器) 和 前端(浏览器)组成,HTTP协议就是负责这里后端和前端的数据交互。
HTTP3.0 之前在传输层是通过 TCP传输的,3.0 版本是通过 UDP传输的。
HTTP协议最主要的应用场景就是做网站,浏览器和服务器之间传输数据,客户端和服务器之间传输数据也很可能是HTTP协议。
网页是通过HTML来构建的 ;HTTP协议是非常典型的"一问一答"的模式
某些网页可能存在一些广告有类似QQ的聊天窗口的功能,例如下图:
这个场景意味着需要服务器主动给浏览器发送消息(消息推送),但是HTTP必须接收到请求才能发送响应,而这里2处,服务器并没有接收到广告方发送的请求而给广告方的浏览器发送了响应,于是应用层还提供了一个协议 websocket(针对HTTP的能力进行了补充)
2 Fiddler的使用
Fiddler是一个抓包工具,抓包工具本质是一个”代理程序“,能获取到网络上传输的数据,并显示出来,从而给程序员提供一些参考。
我们下载好Fiddler ,进入这个界面,点击Tools,然后点击Options:
然后如图把这四个选项打上勾然后点击OK:
在这个过程可能会出现提示让你安装CA证书,根据提示一路确定即可。因为网络上大部分请求都是基于 HTTPS(在HTTP的基础上进行了加密),安装CA证书的目的就是为了解密。除此之外还需要关闭电脑上的其他代理程序。
代理程序就类似于一个中转站:
注意:代理是一个程序,不是一个设备,这个中转是工作在应用层的
客户端和服务器在通信时,代理程序就能记录下请求和响应的具体细节
正向代理:在客户端的应用层中转数据
反向代理:在服务器的应用层中转数据
如果上面Fiddler的安装配置过程没有出错,此时Fiddler就能抓到很多的数据包:
只要电脑上有程序使用了HTTP/HTTPS 就会被Fiddler 获取到 。
现在,我打开百度的官网:
我们发现图中包含 baidu 的交互信息不止一条,因为浏览器和服务器之间的HTTP交互不止一次,通常有很多次,第一次的交互是拿到这个页面的 html ,html还会依赖其他的 css 和 js 图片等,所以html被加载之后,又会触发一些请求获取css js 等。
在上面抓到的数据包中,我们主要关注蓝色的那条
因为蓝色的表示返回的是一个html ,我们双击进入:
在右边的上方代表的是请求的明细,右下方代表的是响应的明细:
上图方框中的选项代表是以什么形式打开,我们选择 Raw 代表没有处理过的最原生的数据 ,接下来我们点击 view Notepad ,可以在记事本打开方便查看:
我们发现响应的数据打开后是乱码的,这是因为为了节省带宽字样资源,数据被压缩过的原因
我们可以点击这个黄色的按钮,解压缩:
然后我们再打开,内容就恢复正常了 ,这个响应的数据就是网页的html
3 HTTP报文格式
HTTP请求包含4个部分:
1.首行:
首行包含三个部分:
第一个是方法 :GET
第二个是URL:百度一下,你就知道
第三个是 版本号:HTTP/1.1
三者之间使用空格分开
2. 请求头:
从第二行一直到最后都是请求头 ,类似于TCP报头/IP报头,重要的属性信息
我们发现请求头中包含了很多键值对,每个键值对占一行,键和值之间使用 ": "来分隔,这里键值对的具体含义是有HTTP协议规定的。
3. 空行:最后一行的回车,请求头的结束标记。
4. 正文:http的载荷部分,有的http请求有,有的没有
HTTP响应格式也是分成4个部分
1. 首行:
HTTP/1.1 代表版本号;200表示状态码;OK表示状态码描述,三个部分使用空格分隔
状态码:表示这次请求是否成功,或者失败的原因
2. 响应头:
响应头,同样是键值对结构
3. 空行
响应头的结束标记 。
4. 正文:
即后面的所有内容
4 认识URL
URL是Uniform Resource Locator(统一资源定位符)的缩写。它是互联网上用于标识和定位资源的地址。
例如上面的:https://www.baidu.com.
https代表协议名称 www.baidu.com 代表域名,这就是一个非常简单的URL。我们在打开的百度中搜索Fiddler就得到了一些更复杂的URL
这里的 s 代表的是 路径,可以类比文件的路径,?后面的都是查询字符串。
一下是一个完整的URL结构:
如果uer:pass放在URL中会不太安全所以现在都是通过单独的登录页面来完成身份验证的。
服务器地址这里也可以填写IP地址。
如果没有填写端口号,浏览器会自动给一个默认的端口,http默认为80 https 443
文件路径用于在服务器中找到具体的资源
查询字符串是针对请求的内容进行一个补充,按照键值对的方式组织,键值对的内容都是程序员定义的
查询字符串中使用&(and符号/取地址符号)分隔两个键值对,使用 = 分隔键和值
5 URL encode
查询字符串中是自定义的键值对,在URL中,本身有些符号具有特定的含义,如果查询字符串中也包含相同的符号,就可能解析失败,所以需要对符号进行转义。
URL编码(URL encoding),也称百分号编码(Percent-encoding),就是一种用于在URL中传输特殊字符的编码方式。URL编码将特殊字符转换为某些格式,以便它们可以安全地被传输和解析。
URL编码使用百分号(%)加上两个十六进制数字来表示特殊字符,其中每个字符都由一个或多个字节组成。例如,空格字符在URL中不能直接使用,因此可以被编码为"%20"。其他特殊字符,如问号(?)、井号(#)、斜杠(/)等也会被 URL 编码为相应的形式。
URL编码通常用于在URL中传递参数和数据,确保这些数据能够被正确地解析和处理,而不会引起歧义。大多数现代Web浏览器和Web服务器都支持URL编码,并且很多编程语言和框架也提供了相关的编码和解码函数。
6. 方法
上面我们说到了HTTP请求的三个部分其中一个部分就是方法,方法描述了这次请求想干什么。
-
GET:从服务器获取资源。GET 方法用于请求服务器发送某个资源,通常用于获取网页、图片、视频等静态内容。
-
POST:向服务器提交数据。POST 方法用于向服务器提交数据,常用于提交表单数据、上传文件等操作。
-
PUT:更新服务器上的资源。PUT 方法用于向服务器上传新的内容,或者替换服务器上的现有内容。
-
DELETE:删除服务器上的资源。DELETE 方法用于请求服务器删除指定的资源。
-
PATCH:局部更新资源。PATCH 方法用于对资源进行局部更新,只修改指定部分内容。
-
HEAD:获取资源的头部信息。HEAD 方法类似于 GET 方法,但服务器只返回响应头部信息,不返回实际内容。
-
OPTIONS:获取服务器支持的方法。OPTIONS 方法用于查询服务器支持的各种方法或功能。
-
TRACE:追踪请求的路径。TRACE 方法用于在目标资源处执行一个请求序列,并在最终将收到的响应消息的传输路径上返回响应。
-
CONNECT:用于代理服务器。CONNECT 方法用于要求代理在与客户端之间建立隧道连接时改变代理行为。
这里每个方法的说明只是标准文档中的使用建议,事实上开发时也可以用GET向服务器提交数据,用POST从服务器获取资源。
这里的方法我们主要掌握GET和POST
6.1 GET 方法:
-
作用:GET 方法主要用于从服务器获取资源,通常用于请求特定资源(如网页、图片、文件等)的数据。
-
参数传递:GET 请求的参数会附加在URL的末尾,以查询字符串的形式出现,例如 http://example.com/api/data?key1=value1&key2=value2。http://example.com/api/data?key1=value1&key2=value2%E3%80%82
-
安全性:GET 请求是幂等的,即多次请求同一URL的结果应该相同。由于参数暴露在URL中,不适合传输敏感信息,因为信息可能会被浏览器、代理服务器或日志记录捕获。
-
缓存:GET 请求可以被缓存,可以通过缓存来提高性能。
-
书签:GET 请求可以被书签化,用户可以将其保存为书签以便日后访问。
6.2 POST 方法:
-
作用:POST 方法主要用于向服务器提交数据,通常用于提交表单数据、上传文件或执行需要数据提交的操作。
-
参数传递:POST 请求的参数通常包含在正文中,而不是URL中,因此对于大量数据和敏感信息的传输更为合适。
-
安全性:POST 请求不会在浏览器历史记录中留下痕迹,并且对发送的数据量没有限制,适合传输敏感信息。
-
幂等性:POST 请求不要求是幂等的,即多次请求同一URL的结果可能会有所不同。
-
缓存:POST 请求默认情况下不会被缓存,因为它可能会对服务器状态进行更改。
总的来说,GET 方法用于获取资源,参数在URL中传递,适合幂等操作和对数据量较小、不敏感的请求;而 POST 方法用于提交数据,参数在请求体中传递,适合非幂等操作、传输敏感信息和对数据量较大的请求。根据需求和场景的不同,选择合适的方法来发送HTTP请求。
面试题:GET和POST有什么区别
功能上:GET和POST本质上没有什么区别,使用GET的场景也可以替换为POST,使用POST的场景也可以替换为GET,主要取决于代码的具体实现。部分服务器或浏览器某些情况下GET和POST不能完美替换,但大部分场景下都可以相互替换。
使用方式上:GET通常把数据放在URL的查询字符串中,POST习惯把数据放在正文中。
幂等性: 标准文档中,建议GET请求实现成幂等的,POST则无要求。
7. 请求头
HTTP请求头是在HTTP请求中包含的一组键值对,用于提供关于请求的额外信息和元数据。请求头位于请求的起始行之后,每个键值对以字段名和字段值的形式表示,用冒号分隔。
以下是一些常见的HTTP请求头:
- Host:指定目标服务器的主机名和端口号。
- User-Agent:标识发起请求的客户端应用程序或用户代理的信息(描述用户操作系统的信息和浏览器的信息,以兼容老设备无法运行新特性,也用于识别电脑手机以展示不同比例的界面)。
- Accept:指定客户端能够处理的响应内容类型,通常是MIME类型。
- Content-Type:指定请求体中的数据类型,例如application/json或application/x-www-form-urlencoded。还可以在后方指定字符编码
- Content-Length:指定请求体的长度(以字节为单位),可以通过这个长度处理粘包问题。
- Authorization:用于对请求进行身份验证的凭据,常见的有基本认证(Basic Authentication)和Bearer令牌(Bearer Token)。
- Cookie:包含之前由服务器设置的一个或多个cookie。
- Referer:指示请求的源URL,用于标识请求是从哪个页面链接过来的(我们浏览网页时会有从一个页面进入另一个页面的场景,Referer就记录了上一个页面的URL)。
- If-Modified-Since:用于条件性请求,指定自从某个日期后资源未被修改时才获取。
- Cache-Control:控制缓存行为,例如no-cache、max-age等。
除了上述常见的请求头,还有许多其他的请求头可以用于不同的目的,具体取决于应用程序和服务器之间的协议约定。通过在请求头中提供这些信息,客户端能够与服务器进行更精确的通信和处理请求。
解释:
Cookie:
Cookie是指由服务器发送到客户端,以便在客户端保存一些数据并在随后的请求中发送回服务器的小型文本文件。通常情况下,它们用于存储有关用户身份验证、会话状态、偏好设置等方面的信息。
Cookie的工作原理如下:
- 当用户访问一个网站时,服务器会将一个或多个Cookie发送给客户端(即用户的浏览器),这些Cookie包含了一些数据和元数据。
- 客户端(即浏览器)接收到Cookie后,将其存储在硬盘上的一个特定位置,以便在随后的请求中发送回服务器。
- 每次客户端向服务器发送请求时,都会将相应的Cookie一并发送回服务器,服务器根据这些Cookie来判断用户的状态、身份验证等信息。
Cookie的使用可以帮助网站实现以下功能:
- 身份验证:当用户成功登录后,服务器可以创建一个包含用户身份验证信息的Cookie,并在随后的请求中使用该Cookie来识别用户身份。
- 会话状态:通过在Cookie中存储会话ID等信息,服务器可以跟踪用户的会话状态,包括用户的浏览历史、购物车内容等。
- 个性化体验:通过存储用户偏好设置等信息,服务器可以为用户提供个性化的服务,例如自定义主题、语言等。
- 跟踪用户行为:通过在Cookie中存储一些跟踪信息,服务器可以收集和分析用户的行为数据,以改善网站的性能和用户体验。
服务器发给客户端的Cookie就相当于一个数据的表格,规定了要存什么信息,客户端存好了,当服务器有需要时直接拿出这个表格发送给服务器。不同网站的Cookie不同,不同共用
Cookie是由服务器发送到客户端的,因此它们可以被第三方恶意攻击者利用来进行跟踪、窃取信息等。出于安全考虑,浏览器通常会限制Cookie的访问范围(例如同源策略),以避免跨站点攻击。
8. 响应头
HTTP响应头与请求头类似,也是一组键值对的集合,用于在HTTP响应中提供有关响应的附加信息和元数据。响应头位于响应的状态行之后,每个键值对以字段名和字段值的形式表示,同样使用冒号进行分隔。
以下是一些常见的HTTP响应头:
- Content-Type:指定响应体的数据类型,例如application/json或text/html。
- Content-Length:指定响应体的长度(以字节为单位)。
- Cache-Control:控制响应的缓存行为,包括no-cache、max-age等指令。
- Set-Cookie:在客户端设置一个或多个cookie。
- Location:指示客户端应重定向到的URL,通常与3xx状态码一起使用。
- Date:指示响应生成的日期和时间。
- Server:包含响应的服务器软件信息。
- ETag:资源的实体标签,用于支持条件请求和缓存验证。
- Last-Modified:指示资源的最后修改日期和时间。
- WWW-Authenticate:用于要求客户端进行身份验证的机制,通常与401状态码一起使用。
除了上述常见的响应头,还有许多其他的响应头可以用于不同的目的,具体取决于应用程序和服务器之间的协议约定。通过在响应头中提供这些信息,服务器能够向客户端提供关于响应内容和处理的详细信息。
9. 状态码
HTTP响应中的状态码是服务器返回给客户端的三位数标识,用于表示请求的处理结果。常见的状态码有以下几种:
-
1xx(信息性状态码):服务器已经收到请求,正在处理中。
-
2xx(成功状态码):服务器成功接收、理解、并处理了请求。
-
3xx(重定向状态码):需要客户端进一步的操作才能完成请求。
-
4xx(客户端错误状态码):客户端发送的请求有误,服务器无法处理。
-
5xx(服务器错误状态码):服务器在处理请求时发生了错误。
状态码的含义可以帮助开发人员快速定位问题和进行故障排查。
以下介绍几个常见的状态码:
- 200 OK 表示“一切顺利”
- 404 Not Found 访问的资源没找到,即url中的路径没有找到
- 403 Forbidden 没有权限访问的资源,例如访问gitee中的私有仓库
- 405 Method Not Allowed 客户端所使用的HTTP方法(如GET、POST、PUT等)不被服务器支持或允许用于请求的资源
- 500 Intemal Server Error 服务器内部错误(服务器挂了)
- 504 Gateway Timeout 访问服务器超时
- 301 Moved Permanently 永久重定向
- 302 Move temporarily 临时重定向
重定向是指当客户端发送一个请求到服务器时,服务器会返回一个特殊的响应,告诉客户端需要采取额外的步骤才能获取所需的资源。这些额外的步骤通常包括重新发送请求到另一个URL,以便获取所需的内容。例如:如果百度换了域名,可以把原来的域名重定向到新的域名,使用原来的域名也能访问
重定向可以分为两种类型:永久重定向和临时重定向。
- 永久重定向:表示请求的资源已被永久移动到新的URL,客户端在以后的请求中应该直接使用新的URL。浏览器会自动缓存这个重定向,导致下次访问时不再请求原始URL,直接跳转到新的URL。
- 临时重定向:表示请求的资源暂时移动到了新的URL,客户端应该暂时使用新的URL来获取资源。浏览器不会缓存这个重定向,每次访问时都会重新请求原始URL,然后根据响应的重定向信息跳转到新的URL。