文章目录
- 1.HTTP协议
-
- 1.1 概念
- 1.2 超文本
- 1.3 W3C
- 1.4 意义
- 2.HTTP协议的内容
-
- 2.1 请求协议
-
- 2.1.1 请求协议的内容
- 2.1.2 分析响应协议报告
-
- 请求行
- 请求头
- 空白行
- 请求体
- 2.2 响应协议
-
- 2.2.1 响应协议的内容
- 2.2.2 分析响应协议报告
-
- 状态行
- 响应头
- 空白行
- 响应体
- 2.3 GET与POST
-
-
- 2.3.1 何时发送GET,何时发送POST?
- 2.3.2 GET与POST的区别
-
1.HTTP协议
1.1 概念
超文本传输协议(Hyper Text Transfer Protocol,HTTP)一个简单的请求响应协议,由W3C它通常在制定时运行TCP以上。它指定了客户端可能发送给服务器的消息和响应。
1.2 超文本
超文本是一种网络文本,通过超链接将不同空间的文本信息组织在一起。超文本是界面范式,用于显示文本和文本之间的相关内容。更简单地说,超文本是一种不同于普通文本的文本,如流媒体(声音、视频和图片)。
1.3 W3C
万维网(W3C)联盟成立于1994年,是Web国际中立技术标准机构在技术领域最具权威性和影响力。W3C已经发布了200多个影响深远的项目Web超文本标记语言广泛应用于行业中的技术标准和实施指南HTML(标准通用标记语言下的应用),可扩展标记语言XML(标准通用标记语言下的子集),帮助残疾人有效获得Web信息无障碍指南(WCAG)等待,有效促进Web技术相互兼容,它在支持互联网技术的发展和应用方面发挥了基本的作用。
1.4 意义
规范浏览器和服务器的数据交互(核心:键值对格式)B/S就结构开发而言,实现了B/S解耦合,因为两者不必互相依赖,只需要遵守HTTP协议即可。
而,字面上有藕断丝连的意思,耦 这个词在语中,这个词指的是两个人在一起耕地,他们互不影响,这也是耦合的起源。 低耦合意味着尽可能减少每个模块或类别之间或方法之间的关系,使它们尽可能独立。一个地方的错误不会影响一切,而且可以提高代码的重用性。
2.HTTP协议的内容
我们可以用F12,然后找到network当我们点击页面中的选项时login按钮,我们的请求将被发出,然后我们可以看到network中出现了一个新的选项我们点击该选项就可以查看相应协议的内容。
2.1 请求协议
接下来,我们将使用代码显示HTTP具体报文。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>http协议</title> </head> <body> <!--注:浏览器上编写的请求路径应带有应用程序的根路径。--> <h1>get请求:</h1> <form action="/servlet05/getServlet" method="get">
username<input type="text" name="username" /><br>
password<input type="password" name="userpwd" /><br>
<input type="submit" value="login">
</form>
<h1>post请求:</h1>
<form action="/servlet05/postServlet" method="post">
username<input type="text" name="username" /><br>
password<input type="password" name="userpwd" /><br>
<input type="submit" value="login">
</form>
</body>
</html>
这段代码中,servlet05是WebAPP的名字,其中我们已经编写了GetServlet和PostServlet。这两个Servlet继承了GenericServlet并重写了其中的service方法。
其中的主要代码是:
//GetServlet
out.println("<!doctype html>");
out.println("<html>");
out.println(" <head>");
out.println(" <title>from get servlet</title>");
out.println(" </head>");
out.println(" <body>");
out.println(" <h1>from get servlet</h1>");
out.println(" </body>");
out.println("</html>");
//PostServlet
out.println("<!doctype html>");
out.println("<html>");
out.println(" <head>");
out.println(" <title>from post servlet</title>");
out.println(" </head>");
out.println(" <body>");
out.println(" <h1>from post servlet</h1>");
out.println(" </body>");
out.println("</html>");
并且已经在/webapp/WEB-INF/web.xml文件中添加了关联:
<servlet>
<servlet-name>getServlet</servlet-name>
<servlet-class>com.bjpowernode.javaweb.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getServlet</servlet-name>
<url-pattern>/getServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>pServlet</servlet-name>
<servlet-class>com.bjpowernode.javaweb.servlet.PostServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>pServlet</servlet-name>
<url-pattern>/postServlet</url-pattern>
</servlet-mapping>
2.1.1 请求协议的内容
HTTP请求(B -> S)协议的内容包括四部分:
- 请求行
- 请求头
- 空白行
- 请求体
HTTP请求协议的具体报文-Get:
GET /servlet05/getServlet?username=lucy&userpwd=1111 HTTP/1.1 请求行
Host: localhost:8080 请求头
Connection: keep-alive
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/servlet05/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
空白行
请求体
HTTP请求协议的具体报文-Post:
POST /servlet05/postServlet HTTP/1.1 请求行
Host: localhost:8080 请求头
Connection: keep-alive
Content-Length: 25
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: http://localhost:8080
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/servlet05/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
空白行
username=lisi&userpwd=123 请求体
2.1.2 响应协议报文的分析
请求行
请求行包括三个部分:第一部分是请求方式(POST/GET…),第二部分是URI(/servlet05/postServlet),第三部分是请求协议版本号(HTTP/1.1 )
-
请求方式一共有7种:
- get(常用的)
- post(常用的)
- delete
- put
- head
- options
- trace
-
URI(统一资源标识符)
- 什么是URI? 统一资源标识符。代表网络中某个资源的名字。但是通过URI是无法定位资源的。
- 什么是URL?统一资源定位符。代表网络中某个资源,同时,通过URL是可以定位到该资源的。
- URI和URL什么关系,有什么区别?
- URL包括URI
- http://localhost:8080/servlet05/index.html 这是URL。
- /servlet05/index.html 这是URI。
-
HTTP协议版本号,具体可以参考https://network.51cto.com/article/679706.html
请求头
- 请求的主机(localhost,这里我们是用本机做实验,所以ip地址是localhost)
- 主机的端口(8080)
- 浏览器信息
- 平台信息
- cookie等信息
- …
空白行
空白行是用来区分“请求头”和“请求体”。
请求体
向服务器发送的具体数据。比如我们form表格中的信息(username=lisi&userpwd=123 )。如果是使用get请求那么这一行是空的。
2.2 响应协议
同样的,我们仍可以使用F12,然后找到network选项,当我们点击页面中的login按钮,我们的请求就会被发出,然后可以看到network中出现了一个新的选项我们点击该选项就可以查看相应协议的内容。
2.2.1 响应协议的内容
HTTP响应(S -> B)协议的内容包括四部分:
- 状态行
- 响应头
- 空白行
- 响应体
HTTP响应协议的具体报文:
HTTP/1.1 200 ok 状态行
Content-Type: text/html;charset=UTF-8 响应头
Content-Length: 160
Date: Mon, 08 Nov 2021 13:19:32 GMT
Keep-Alive: timeout=20
Connection: keep-alive
空白行
<!doctype html> 响应体
<html>
<head>
<title>from get servlet</title>
</head>
<body>
<h1>from get servlet</h1>
</body>
</html>
2.2.2 响应协议报文的分析
状态行
状态行包括3个部分。第一部分是关于HTTP协议的版本号(HTTP/1.1),第二部分是状态码(200),第三部分是状态的描述信息(ok)。
-
关于协议版本号具体可参考:https://network.51cto.com/article/679706.html
-
常见的状态码有200(访问正常结束)、404(访问资源失败,这个时候要么是路径写错了,要么是服务器未启动成功)、405(前端发送的请求与后端处理的请求方式不一致导致的,比如说前端发送get请求,而后端使用post处理)、500(当服务器的程序出错会出现该状态码)。。
-
状态描述信息:ok(访问正常结束)not found(资源找不到)
响应头
- 响应的内容类型:text/html;charset=UTF-8
- 响应的内容长度:160
- 响应的时间
- …
空白行
空白行就是用来分割响应头和响应体的。
响应体
响应体就是响应的正文,这些内容是一个长的字符串,这个字符串被浏览器渲染,解释并执行,最终展示出效果。
2.3 GET与POST
2.3.1 什么时候发送的是GET,什么时候发送的是POST?
到目前为止,,并且form标签中的method属性值为:method=“post”。
其他所有情况一律都是get请求:
- 在浏览器地址栏上直接输入URL,敲回车,属于get请求。
- 在浏览器上直接点击超链接,属于get请求。
- 使用form表单提交数据时,form标签中没有写method属性,默认就是get
- 或者使用form的时候,form标签中method属性值为:method=“get”
- …
2.3.2 GET与POST的区别
- get请求发送数据的时候,数据会挂在URI的后面,并且在URI后面添加一个“?”,"?"后面是数据。这样会导致发送的数据回显在浏览器的地址栏上。(get请求在“请求行”上发送数据)
- http://localhost:8080/servlet05/getServlet?username=zhangsan&userpwd=1111
- post请求发送数据的时候,在请求体当中发送。不会回显到浏览器的地址栏上。也就是说post发送的数据,在浏览器地址栏上看不到。(post在“请求体”当中发送数据)
- get请求只能发送普通的字符串。并且发送的字符串长度有限制,不同的浏览器限制不同。这个没有明确的规范。
- get请求无法发送大数据量。
- post请求可以发送任何类型的数据,包括普通字符串,流媒体等信息:视频、声音、图片。
- post请求可以发送大数据量,理论上没有长度限制。
- get请求在W3C中是这样说的:get请求比较适合从服务器端获取数据。
- post请求在W3C中是这样说的:post请求比较适合向服务器端传送数据。
- get请求是安全的。get请求是绝对安全的。为什么?因为get请求只是为了从服务器上获取数据。不会对服务器造成威胁。
- post请求是危险的。为什么?因为post请求是向服务器提交数据,如果这些数据通过后门的方式进入到服务器当中,服务器是很危险的。另外post是为了提交数据,所以一般情况下拦截请求的时候,大部分会选择拦截(监听)post请求。
-
get请求支持缓存。
- 如果我们不希望get请求走缓存,怎么办?怎么避免走缓存?我希望每一次这个get请求都去服务器上找资源,我不想从本地浏览器的缓存中取。
- 只要每一次get请求的请求路径不同即可。
- https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=789789787897898
- https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=789789787897899
- https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=系统毫秒数
- 怎么解决?可以在路径的后面添加一个每时每刻都在变化的“时间戳”,这样,每一次的请求路径都不一样,浏览器就不走缓存了。
- 如果我们不希望get请求走缓存,怎么办?怎么避免走缓存?我希望每一次这个get请求都去服务器上找资源,我不想从本地浏览器的缓存中取。
-
post请求不支持缓存。(POST是用来修改服务器端的资源的。)
- post请求之后,服务器“响应的结果”不会被浏览器缓存起来。因为这个缓存没有意义。