第四章 XML_Tomcat10_HTTP
一 XML
XML是EXtensible Markup Language的缩写,翻译过来就是可扩展标记语言。所以很明显,XML和HTML一样都是标记语言,也就是说它们的基本语法都是标签。
-
可扩展 三个字表面上的意思是XML允许自定义格式。但这不代表你可以随便写。
-
在XML基本语法规范的基础上,你使用的那些第三方应用程序、框架会通过XML约束的方式强制规定配置文件中可以写什么和怎么写
-
XML基本语法这个知识点的定位是:我们不需要从零开始,从头到尾的一行一行编写XML文档,而是在第三方应用程序、框架已提供的配置文件的基础上修改。要改成什么样取决于你的需求,而怎么改取决XML基本语法和具体的XML约束。
1.1 常见配置文件类型
- properties文件,例如druid连接池就是使用properties文件作为配置文件
- XML文件,例如Tomcat就是使用XML文件作为配置文件
- YAML文件,例如SpringBoot就是使用YAML作为配置文件
- json文件,通常用来做文件传输,也可以用来做前端或者移动端的配置文件
- 等等...
1.1.1 properties配置文件
示例
.properties
atguigu.jdbc.url=jdbc:mysql://localhost:3306/atguigu
atguigu.jdbc.driver=com.mysql.cj.jdbc.Driver
atguigu.jdbc.username=root
atguigu.jdbc.password=root
语法规范
- 由键值对组成
- 键和值之间的符号是等号
- 每一行都必须顶格写,前面不能有空格之类的其他符号
1.1.2 xml配置文件
示例
xml
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<name>张三</name>
<age>18</age>
</student>
<student>
<name>李四</name>
<age>20</age>
</student>
</students>
XML的基本语法
- XML的基本语法和HTML的基本语法简直如出一辙。其实这不是偶然的,XML基本语法+HTML约束=HTML语法。在逻辑上HTML确实是XML的子集。
- XML文档声明 这部分基本上就是固定格式,要注意的是文档声明一定要从第一行第一列开始写
xml
<?xml version="1.0" encoding="UTF-8"?>
- 根标签
- 根标签有且只能有一个。
- 标签关闭
- 双标签:开始标签和结束标签必须成对出现。
- 单标签:单标签在标签内关闭。
- 标签嵌套
- 可以嵌套,但是不能交叉嵌套。
- 注释不能嵌套
- 标签名、属性名建议使用小写字母
- 属性
- 属性必须有值
- 属性值必须加引号,单双都行
XML的约束(稍微了解)
将来我们主要就是根据XML约束中的规定来编写XML配置文件,而且会在我们编写XML的时候根据约束来提示我们编写, 而XML约束主要包括DTD和Schema两种。
- DTD
- Schema
Schema约束要求我们一个XML文档中,所有标签,所有属性都必须在约束中有明确的定义。
下面我们以web.xml的约束声明为例来做个说明:
xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
1.2 DOM4J进行XML解析
1.2.1 DOM4J的使用步骤
- 导入jar包 dom4j.jar
- 创建解析器对象(SAXReader)
- 解析xml 获得Document对象
- 获取根节点RootElement
- 获取根节点下的子节点
1.2.2 DOM4J的API介绍
1.创建SAXReader对象
java
SAXReader saxReader = new SAXReader();
- 解析XML获取Document对象: 需要传入要解析的XML文件的字节输入流
java
Document document = reader.read(inputStream);
- 获取文档的根标签
java
Element rootElement = documen.getRootElement()
- 获取标签的子标签
java
//获取所有子标签
List<Element> sonElementList = rootElement.elements();
//获取指定标签名的子标签
List<Element> sonElementList = rootElement.elements("标签名");
- 获取标签体内的文本
java
String text = element.getText();
- 获取标签的某个属性的值
java
String value = element.attributeValue("属性名");
二 Tomcat10
2.1 WEB服务器
Web服务器通常由硬件和软件共同构成。
- 硬件:电脑,提供服务供其它客户电脑访问
- 软件:电脑上安装的服务器软件,安装后能提供服务给网络中的其他计算机,将本地文件映射成一个虚拟的url地址供网络中的其他人访问。
常见的JavaWeb服务器:
- Tomcat(Apache):当前应用最广的JavaWeb服务器
- Jetty:更轻量级、更灵活的servlet容器
- JBoss(Redhat红帽):支持JavaEE,应用比较广EJB容器 --> SSH轻量级的框架代替
- GlassFish(Orcale):Oracle开发JavaWeb服务器,应用不是很广
- Resin(Caucho):支持JavaEE,应用越来越广
- Weblogic(Orcale):要钱的!支持JavaEE,适合大型项目
- Websphere(IBM):要钱的!支持JavaEE,适合大型项目
2.2 Tomcat服务器
2.2.1 简介
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
2.2.2 安装
版本
- 版本:企业用的比较广泛的是8.0和9.0,目前比较新正式发布版本是Tomcat10.0, Tomcat11仍然处于测试阶段。
- JAVAEE 版本和Servlet版本号对应关系 Jakarta EE Releases
Servlet Version | EE Version |
---|---|
6.1 | Jakarta EE ? |
6.0 | Jakarta EE 10 |
5.0 | Jakarta EE 9/9.1 |
4.0 | JAVA EE 8 |
3.1 | JAVA EE 7 |
3.1 | JAVA EE 7 |
3.0 | JAVAEE 6 |
- Tomcat 版本和Servlet版本之间的对应关系
Servlet Version | **Tomcat ** Version | JDK Version |
---|---|---|
6.1 | 11.0.x | 17 and later |
6.0 | 10.1.x | 11 and later |
5.0 | 10.0.x (superseded) | 8 and later |
4.0 | 9.0.x | 8 and later |
3.1 | 8.5.x | 7 and later |
3.1 | 8.0.x (superseded) | 7 and later |
3.0 | 7.0.x (archived) | 6 and later (7 and later for WebSocket) |
下载
- Tomcat官方网站:http://tomcat.apache.org/
- 安装版:需要安装,一般不考虑使用。
- 解压版: 直接解压缩使用,我们使用的版本。
安装
- 正确安装JDK并配置JAVA_HOME(以JDK17为例 https://injdk.cn中可以下载各种版本的JDK)
- 解压tomcat到非中文无空格目录
- 点击bin/startup.bat启动
- 打开浏览器输入 http://localhost:8080访问测试
- 直接关闭窗口或者运行 bin/shutdown.bat关闭tomcat
- 处理dos窗口日志中文乱码问题: 修改conf/logging.properties,将所有的UTF-8修改为GBK
- 修改前
- 修改后
- 重启测试
2.3 Tomcat目录及测试
C:\Program4java\apache-tomcat-10.1.7 这个目录下直接包含Tomcat的bin目录,conf目录等,我们称之为Tomcat的安装目录或根目录。
-
bin:该目录下存放的是二进制可执行文件,如果是安装版,那么这个目录下会有两个exe文件:tomcat10.exe、tomcat10w.exe,前者是在控制台下启动Tomcat,后者是弹出GUI窗口启动Tomcat;如果是解压版,那么会有startup.bat和shutdown.bat文件,startup.bat用来启动Tomcat,但需要先配置JAVA_HOME环境变量才能启动,shutdawn.bat用来停止Tomcat;
-
conf:这是一个非常非常重要的目录,这个目录下有四个最为重要的文件:
-
server.xml:配置整个服务器信息。例如修改端口号。默认HTTP请求的端口号是:8080
-
tomcat-users.xml:存储tomcat用户的文件,这里保存的是tomcat的用户名及密码,以及用户的角色信息。可以按着该文件中的注释信息添加tomcat用户,然后就可以在Tomcat主页中进入Tomcat Manager页面了;
html<tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0"> <role rolename="admin-gui"/> <role rolename="admin-script"/> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <user username="admin" password="admin" roles="admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" /> </tomcat-users>
web.xml:部署描述符文件,这个文件中注册了很多MIME类型,即文档类型。这些MIME类型是客户端与服务器之间说明文档类型的,如用户请求一个html网页,那么服务器还会告诉客户端浏览器响应的文档是text/html类型的,这就是一个MIME类型。客户端浏览器通过这个MIME类型就知道如何处理它了。当然是在浏览器中显示这个html文件了。但如果服务器响应的是一个exe文件,那么浏览器就不可能显示它,而是应该弹出下载窗口才对。MIME就是用来说明文档的内容是什么类型的!
-
context.xml:对所有应用的统一配置,通常我们不会去配置它。
-
-
lib:Tomcat的类库,里面是一大堆jar文件。如果需要添加Tomcat依赖的jar文件,可以把它放到这个目录中,当然也可以把应用依赖的jar文件放到这个目录中,这个目录中的jar所有项目都可以共享之,但这样你的应用放到其他Tomcat下时就不能再共享这个目录下的jar包了,所以建议只把Tomcat需要的jar包放到这个目录下;
-
logs:这个目录中都是日志文件,记录了Tomcat启动和关闭的信息,如果启动Tomcat时有错误,那么异常也会记录在日志文件中。
-
temp:存放Tomcat的临时文件,这个目录下的东西可以在停止Tomcat后删除!
-
webapps:存放web项目的目录,其中每个文件夹都是一个项目;如果这个目录下已经存在了目录,那么都是tomcat自带的项目。其中ROOT是一个特殊的项目,在地址栏中访问:http://127.0.0.1:8080,没有给出项目目录时,对应的就是ROOT项目.http://localhost:8080/examples,进入示例项目。其中examples"就是项目名,即文件夹的名字。
-
work:运行时生成的文件,最终运行的文件都在这里。通过webapps中的项目生成的!可以把这个目录下的内容删除,再次运行时会生再次生成work目录。当客户端用户访问一个JSP文件时,Tomcat会通过JSP生成Java文件,然后再编译Java文件生成class文件,生成的java和class文件都会存放到这个目录下。
-
LICENSE:许可证。
-
NOTICE:说明文件。
2.4 WEB项目的标准结构
一个标准的可以用于发布的WEB项目标准结构如下
- app 本应用根目录
- static 非必要目录,约定俗成的名字,一般在此处放静态资源 ( css js img)
- WEB-INF 必要目录,必须叫WEB-INF,受保护的资源目录,浏览器通过url不可以直接访问的目录
- classes 必要目录,src下源代码,配置文件,编译后会在该目录下,web项目中如果没有源码,则该目录不会出现
- lib 必要目录,项目依赖的jar编译后会出现在该目录下,web项目要是没有依赖任何jar,则该目录不会出现
- web.xml 必要文件,web项目的基本配置文件. 较新的版本中可以没有该文件,但是学习过程中还是需要该文件
- index.html 非必要文件,index.html/index.htm/index.jsp为默认的欢迎页
url的组成部分和项目中资源的对应关系
2.5 WEB项目部署的方式
方式1 直接将编译好的项目放在webapps目录下 (已经演示)
方式2 将编译好的项目打成war包放在webapps目录下,tomcat启动后会自动解压war包(其实和第一种一样)
方式3 可以将项目放在非webapps的其他目录下,在tomcat中通过配置文件指向app的实际磁盘路径
- 在磁盘的自定义目录上准备一个app
- 在tomcat的conf下创建Catalina/localhost目录,并在该目录下准备一个app.xml文件
xml
<!--
path: 项目的访问路径,也是项目的上下文路径,就是在浏览器中,输入的项目名称
docBase: 项目在磁盘中的实际路径
-->
<Context path="/app" docBase="D:\mywebapps\app" />
- 启动tomcat访问测试即可
2.6 IDEA中开发并部署运行WEB项目
2.6.1 IDEA关联本地Tomcat
可以在创建项目前设置本地tomcat,也可以在打开某个项目的状态下找到settings
找到 Build,Execution,Eeployment下的Application Servers ,找到+号
选择Tomcat Server
选择tomcat的安装目录
点击ok
关联完毕
2.6.2 IDEA创建web工程
推荐先创建一个空项目,这样可以在一个空项目下同时存在多个modules,不用后续来回切换之前的项目,当然也可以忽略此步直接创建web项目
检查项目的SDK,语法版本,以及项目编译后的输出目录
先创建一个普通的JAVA项目
检查各项信息是否填写有误
创建完毕后,为项目添加Tomcat依赖
选择modules,添加 framework support
选择Web Application 注意Version,勾选 Create web.xml
删除index.jsp ,替换为 index.html
处理配置文件
- 在工程下创建resources目录,专门用于存放配置文件(都放在src下也行,单独存放可以尽量避免文件集中存放造成的混乱)
- 标记目录为资源目录,不标记的话则该目录不参与编译
- 标记完成后,显示效果如下
处理依赖jar包问题
- 在WEB-INF下创建lib目录
- 必须在WEB-INF下,且目录名必须叫lib!!!
- 复制jar文件进入lib目录
- 将lib目录添加为当前项目的依赖,后续可以用maven统一解决
- 环境级别推荐选择module 级别,降低对其他项目的影响,name可以空着不写
- 查看当前项目有那些环境依赖
- 在此位置,可以通过-号解除依赖
2.6.3 IDEA部署-运行web项目
检查idea是否识别modules为web项目并存在将项目构建成发布结构的配置
- 就是检查工程目录下,web目录有没有特殊的识别标记
- 以及artifacts下,有没有对应 _war_exploded,如果没有,就点击+号添加
点击向下箭头,出现 Edit Configurations选项
出现运行配置界面
点击+号,添加本地tomcat服务器
因为IDEA 只关联了一个Tomcat,红色部分就只有一个Tomcat可选
选择Deployment,通过+添加要部署到Tomcat中的artifact
applicationContext中是默认的项目上下文路径,也就是url中需要输入的路径,这里可以自己定义,可以和工程名称不一样,也可以不写,但是要保留/,我们这里暂时就用默认的
点击apply 应用后,回到Server部分. After Launch是配置启动成功后,是否默认自动打开浏览器并输入URL中的地址,HTTP port是Http连接器目前占用的端口号
点击OK后,启动项目,访问测试
- 绿色箭头是正常运行模式
- "小虫子"是debug运行模式
- 点击后,查看日志状态是否有异常
- 浏览器自动打开并自动访问了index.html欢迎页
工程结构和可以发布的项目结构之间的目录对应关系
IDEA部署并运行项目的原理
- idea并没有直接进将编译好的项目放入tomcat的webapps中
- idea根据关联的tomcat,创建了一个tomcat副本,将项目部署到了这个副本中
- idea的tomcat副本在C:\用户\当前用户\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\中
- idea的tomcat副本并不是一个完整的tomcat,副本里只是准备了和当前项目相关的配置文件而已
- idea启动tomcat时,是让本地tomcat程序按照tomcat副本里的配置文件运行
- idea的tomcat副本部署项目的模式是通过conf/Catalina/localhost/*.xml配置文件的形式实现项目部署的
三 HTTP协议
3.1 HTTP简介
HTTP 超文本传输协议 (HTTP-Hyper Text transfer protocol),是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过十几年的使用与发展,得到不断地完善和扩展。它是一种详细规定了浏览器和万维网服务器之间互相通信的规则 ,通过因特网传送万维网文档的数据传送协议。客户端与服务端通信时传输的内容我们称之为报文 。HTTP协议就是规定报文的格式。HTTP就是一个通信规则,这个规则规定了客户端发送给服务器的报文格式,也规定了服务器发送给客户端的报文格式。实际我们要学习的就是这两种报文。客户端发送给服务器的称为"请求报文 ",服务器发送给客户端的称为"响应报文"。
3.1.1 发展历程
HTTP/0.9
- 蒂姆伯纳斯李是一位英国计算机科学家,也是万维网的发明者。他在 1989 年创建了单行 HTTP 协议。它只是返回一个网页。这个协议在 1991 年被命名为 HTTP/0.9。
HTTP/1.0
- 1996 年,HTTP/1.0 发布。该规范是显著扩大,并且支持三种请求方法:GET,Head,和POST。
- HTTP/1.0 相对于 HTTP/0.9 的改进如下:
- 每个请求都附加了 HTTP 版本。
- 在响应开始时发送状态代码。
- 请求和响应都包含 HTTP 报文头。
- 内容类型能够传输 HTML 文件以外的文档。
- 但是,HTTP/1.0 不是官方标准。
HTTP/1.1
-
HTTP 的第一个标准化版本 HTTP/1.1 ( RFC 2068 ) 于 1997 年初发布,支持七种请求方法:OPTIONS,GET,HEAD,POST,PUT,DELETE,和TRACE
-
HTTP/1.1 是 HTTP 1.0 的增强:
-
虚拟主机允许从单个 IP 地址提供多个域。
-
持久连接和流水线连接允许 Web 浏览器通过单个持久连接发送多个请求。
-
缓存支持节省了带宽并使响应速度更快。
-
-
HTTP/1.1 在接下来的 15 年左右将非常稳定。
-
在此期间,出现了 HTTPS(安全超文本传输协议)。它是使用 SSL/TLS 进行安全加密通信的 HTTP 的安全版本。
HTTP/2
- 由IETF在2015年发布。HTTP/2旨在提高Web性能,减少延迟,增加安全性,使Web应用更加快速、高效和可靠。
- 多路复用:HTTP/2 允许同时发送多个请求和响应,而不是像 HTTP/1.1 一样只能一个一个地处理。这样可以减少延迟,提高效率,提高网络吞吐量。
- 二进制传输:HTTP/2 使用二进制协议,与 HTTP/1.1 使用的文本协议不同。二进制协议可以更快地解析,更有效地传输数据,减少了传输过程中的开销和延迟。
- 头部压缩:HTTP/2 使用 HPACK 算法对 HTTP 头部进行压缩,减少了头部传输的数据量,从而减少了网络延迟。
- 服务器推送:HTTP/2 支持服务器推送,允许服务器在客户端请求之前推送资源,以提高性能。
- 改进的安全性:HTTP/2 默认使用 TLS(Transport Layer Security)加密传输数据,提高了安全性。
- 兼容 HTTP/1.1:HTTP/2 可以与 HTTP/1.1 共存,服务器可以同时支持 HTTP/1.1 和 HTTP/2。如果客户端不支持 HTTP/2,服务器可以回退到 HTTP/1.1。
HTTP/3
-
于 2021 年 5 月 27 日发布 , HTTP/3 是一种新的、快速、可靠且安全的协议,适用于所有形式的设备。 HTTP/3 没有使用 TCP,而是使用谷歌在 2012 年开发的新协议 QUIC
-
HTTP/3 是继 HTTP/1.1 和 HTTP/2之后的第三次重大修订。
-
HTTP/3 带来了革命性的变化,以提高 Web 性能和安全性。设置 HTTP/3 网站需要服务器和浏览器支持。
-
目前,谷歌云、Cloudflare和Fastly支持 HTTP/3。Chrome、Firefox、Edge、Opera 和一些移动浏览器支持 HTTP/3。
3.1.2 HTTP协议的会话方式
浏览器与服务器之间的通信过程要经历四个步骤
- 浏览器与WEB服务器的连接过程是短暂的,每次连接只处理一个请求和响应。对每一个页面的访问,浏览器与WEB服务器都要建立一次单独的连接。
- 浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应对。
3.1.3 HTTP1.0和HTTP1.1的区别
在HTTP1.0版本中,浏览器请求一个带有图片的网页,会由于下载图片而与服务器之间开启一个新的连接;但在HTTP1.1版本中,允许浏览器在拿到当前请求对应的全部资源后再断开连接,提高了效率。
3.1.4 在浏览器中通过F12工具抓取请求响应报文包
几乎所有的PC端浏览器都支持了F12开发者工具,只不过不同的浏览器工具显示的窗口有差异
3.2 请求和响应报文
3.2.1 报文的格式
主体上分为报文首部和报文主体,中间空行隔开
报文部首可以继续细分为 "行" 和 "头"
3.2.2 请求报文
客户端发给服务端的报文
- 请求报文格式
- 请求首行(请求行); GET/POST 资源路径?参数 HTTP/1.1
- 请求头信息(请求头);
- 空行;
- 请求体;POST请求才有请求体
浏览器 f12 网络下查看请求数据包
form表单发送GET请求特点
1、由于请求参数在请求首行中已经携带了,所以没有请求体,也没有请求空行
2、请求参数拼接在url地址中,地址栏可见[url?name1=value1&name2=value2],不安全
3、由于参数在地址栏中携带,所以由大小限制[地址栏数据大小一般限制为4k],只能携带纯文本
4、get请求参数只能上传文本数据
5、没有请求体。所以封装和解析都快,效率高, 浏览器默认提交的请求都是get请求比如:地址栏输入回车,超链接,表单默认的提交方式
查看GET请求行,请求头,请求体
- 请求行组成部分
- 请求方式 GET
- 访问服务器的资源路径?参数1=值1&参数2=值2 ... ...
- 协议及版本 HTTP/1.1
http
GET /05_web_tomcat/login_success.html?username=admin&password=123213 HTTP/1.1
- 请求头
http
-主机虚拟地址
Host: localhost:8080
-长连接
Connection: keep-alive
-请求协议的自动升级[http的请求,服务器却是https的,浏览器自动会将请求协议升级为https的]
Upgrade-Insecure-Requests: 1
- 用户系统信息
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36
- 浏览器支持的文件类型
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
- 当前页面的上一个页面的路径[当前页面通过哪个页面跳转过来的]: 可以通过此路径跳转回上一个页面, 广告计费,防止盗链
Referer: http://localhost:8080/05_web_tomcat/login.html
- 浏览器支持的压缩格式
Accept-Encoding: gzip, deflate, br
- 浏览器支持的语言
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
-
请求空行
-
请求体
- GET请求数据不放在请求体
form表单发送post请求特点
1、POST请求有请求体,而GET请求没有请求体。
2、post请求数据在请求体中携带,请求体数据大小没有限制,可以用来上传所有内容[文件、文本]
3、只能使用post请求上传文件
4、post请求报文多了和请求体相关的配置[请求头]
5、地址栏参数不可见,相对安全
6、post效率比get低
- POST请求要求将form标签的method的属性设置为post
查看post的请求行 请求头 请求体
- 请求行组成部分
- 请求方式 POST
- 访问服务器的资源路径?参数1=值1&参数2=值2 ... ...
- 协议及版本 HTTP/1.1
http
POST /05_web_tomcat/login_success.html HTTP/1.1
- 请求头
http
Host: localhost:8080
Connection: keep-alive
Content-Length: 31 -请求体内容的长度
Cache-Control: max-age=0 -无缓存
Origin: http://localhost:8080
Upgrade-Insecure-Requests: 1 -协议的自动升级
Content-Type: application/x-www-form-urlencoded -请求体内容类型[服务器根据类型解析请求体参数]
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://localhost:8080/05_web_tomcat/login.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie:JSESSIONID-
-
请求空行
-
请求体:浏览器提交给服务器的数据
http
username=admin&password=1232131
3.2.3 响应报文
响应报文格式
- 响应首行(响应行); 协议/版本 状态码 状态码描述
- 响应头信息(响应头);
- 空行;
- 响应体;
- 响应行组成部分
- 协议及版本 HTTP/1.1
- 响应状态码 200
- 状态描述 OK (缺省)
http
HTTP/1.1 200 OK
说明:响应协议为HTTP1.1,响应状态码为200,表示请求成功;
- 响应头
http
Server: Apache-Coyote/1.1 服务器的版本信息
Accept-Ranges: bytes
ETag: W/"157-1534126125811"
Last-Modified: Mon, 13 Aug 2018 02:08:45 GMT
Content-Type: text/html 响应体数据的类型[浏览器根据类型解析响应体数据]
Content-Length: 157 响应体内容的字节数
Date: Mon, 13 Aug 2018 02:47:57 GMT 响应的时间,这可能会有8小时的时区差
- 响应体
html
<!--需要浏览器解析使用的内容[如果响应的是html页面,最终响应体内容会被浏览器显示到页面中]-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
恭喜你,登录成功了...
</body>
</html>
响应状态码:响应码对浏览器来说很重要,它告诉浏览器响应的结果。比较有代表性的响应码如下:
- 200: 请求成功,浏览器会把响应体内容(通常是html)显示在浏览器中;
- 302: 重定向,当响应码为302时,表示服务器要求浏览器重新再发一个请求,服务器会发送一个响应头Location指定新请求的URL地址;
- 304: 使用了本地缓存
- 404: 请求的资源没有找到,说明客户端错误的请求了不存在的资源;
- 405: 请求的方式不允许
- 500: 请求资源找到了,但服务器内部出现了错误;
更多的响应状态码
状态码 | 状态码英文描述 | 中文含义 |
---|---|---|
1** | ||
100 | Continue | 继续。客户端应继续其请求 |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
2** | ||
200 | OK | 请求成功。一般用于GET与POST请求 |
201 | Created | 已创建。成功请求并创建了新的资源 |
202 | Accepted | 已接受。已经接受请求,但未处理完成 |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
3** | ||
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
306 | Unused | 已经被废弃的HTTP状态码 |
307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
4** | ||
400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
401 | Unauthorized | 请求要求用户的身份认证 |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
409 | Conflict | 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突 |
410 | Gone | 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
412 | Precondition Failed | 客户端请求信息的先决条件错误 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
416 | Requested range not satisfiable | 客户端请求的范围无效 |
417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
5** | ||
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
第四章 XML_Tomcat10_HTTP
一 XML
XML是EXtensible Markup Language的缩写,翻译过来就是可扩展标记语言。所以很明显,XML和HTML一样都是标记语言,也就是说它们的基本语法都是标签。
-
可扩展三个字表面上的意思是XML允许自定义格式。但这不代表你可以随便写。
-
在XML基本语法规范的基础上,你使用的那些第三方应用程序、框架会通过XML约束的方式强制规定配置文件中可以写什么和怎么写。
-
XML基本语法这个知识点的定位是:我们不需要从零开始,从头到尾的一行一行编写XML文档,而是在第三方应用程序、框架已提供的配置文件的基础上修改。要改成什么样取决于你的需求,而怎么改取决XML基本语法和具体的XML约束。
1.1 常见配置文件类型
- properties文件:例如Druid连接池就是使用properties文件作为配置文件。它以简单的键值对形式存储配置信息,非常适合配置一些较为基础、数量不多且结构简单的参数。在实际应用中,通过读取properties文件,程序能够灵活地获取不同环境下的配置,比如数据库连接信息、系统参数等。
- XML文件:例如Tomcat就是使用XML文件作为配置文件。XML凭借其良好的结构化和扩展性,能清晰地描述复杂的配置关系,适用于需要对多个模块、多种类型的配置进行管理的场景。像Tomcat的众多服务器设置,如端口号、虚拟主机、应用部署等都能通过XML文件进行精准配置。
- YAML文件:例如Spring Boot就是使用YAML作为配置文件。YAML以简洁的语法和分层结构来表达配置数据,具有极高的可读性,特别适合在Spring生态系统中,对大量的配置属性进行清晰、简洁的管理。在配置微服务的各种参数、组件依赖等方面,YAML展现出了其独特的优势。
- JSON文件:通常用来做文件传输,也可以用来做前端或者移动端的配置文件。JSON格式简洁紧凑,易于在不同平台和语言之间进行数据交换。在前端开发中,常使用JSON来配置页面的布局、样式、数据接口等信息;在移动端,也可用于配置应用的初始化参数、功能开关等。
- 等等:除了上述常见的配置文件类型,还有一些特定领域或框架所使用的自定义配置文件格式。例如,在一些游戏开发中,可能会使用特定格式的配置文件来管理游戏关卡、角色属性等;在某些工业控制系统中,也会有专门设计的配置文件来设置设备参数、运行逻辑等。
1.1.1 properties配置文件
示例
properties
atguigu.jdbc.url=jdbc:mysql://localhost:3306/atguigu
atguigu.jdbc.driver=com.mysql.cj.jdbc.Driver
atguigu.jdbc.username=root
atguigu.jdbc.password=root
语法规范
- 由键值对组成,每个键值对在文件中独占一行,清晰地划分不同的配置项。
- 键和值之间的符号是等号,这种简单直接的连接方式,方便程序解析和读取。
- 每一行都必须顶格写,前面不能有空格之类的其他符号,确保了语法的严格性和一致性,避免因格式问题导致的解析错误。
1.1.2 xml配置文件
示例
xml
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<name>张三</name>
<age>18</age>
</student>
<student>
<name>李四</name>
<age>20</age>
</student>
</students>
XML的基本语法
- XML的基本语法和HTML的基本语法简直如出一辙。其实这不是偶然的,XML基本语法 + HTML约束 = HTML语法。在逻辑上HTML确实是XML的子集。
- XML文档声明:这部分基本上就是固定格式,要注意的是文档声明一定要从第一行第一列开始写。
xml
<?xml version="1.0" encoding="UTF-8"?>
这里的version
属性指定了XML的版本号,目前广泛使用的是1.0版本。encoding
属性则规定了文档所使用的字符编码,UTF - 8是一种常用的支持多语言的编码方式,能够确保文档在不同系统和环境下准确地展示各种字符。
- 根标签
- 根标签有且只能有一个。它就像是一棵大树的树干,所有其他的标签都是从根标签衍生出来的树枝和树叶。在一个完整的XML文档中,根标签定义了文档的整体结构和主题范围。例如在上述示例中,
<students>
就是根标签,它表示整个文档是关于学生信息的集合。
- 根标签有且只能有一个。它就像是一棵大树的树干,所有其他的标签都是从根标签衍生出来的树枝和树叶。在一个完整的XML文档中,根标签定义了文档的整体结构和主题范围。例如在上述示例中,
- 标签关闭
- 双标签 :开始标签和结束标签必须成对出现。这就如同一个容器,开始标签打开容器,结束标签关闭容器,确保数据的完整性和层次性。例如
<name>张三</name>
,<name>
是开始标签,</name>
是结束标签,它们之间包裹着具体的学生名字信息。 - 单标签 :单标签在标签内关闭。单标签通常用于表示一些不需要包含具体内容的元素,例如
<br />
表示换行,<img src="image.jpg" />
用于插入图片,它们在一个标签内就完成了所有的定义。
- 双标签 :开始标签和结束标签必须成对出现。这就如同一个容器,开始标签打开容器,结束标签关闭容器,确保数据的完整性和层次性。例如
- 标签嵌套
- 可以嵌套,但是不能交叉嵌套。合理的标签嵌套能够构建出清晰的层次结构,就像一个文件夹中可以包含多个子文件夹,子文件夹又可以包含文件一样。例如
<students>
根标签下嵌套多个<student>
标签,每个<student>
标签又嵌套<name>
和<age>
标签,以此来组织学生的相关信息。但如果出现交叉嵌套,如<student><name>张三</student></name>
,就会导致语法错误,使文档无法被正确解析。
- 可以嵌套,但是不能交叉嵌套。合理的标签嵌套能够构建出清晰的层次结构,就像一个文件夹中可以包含多个子文件夹,子文件夹又可以包含文件一样。例如
- 注释不能嵌套 :XML中的注释以
<!--
开始,以-->
结束,用于对文档中的部分内容进行解释说明,方便开发人员理解和维护代码。但注释不能在内部再包含其他注释,例如<!--这是一个注释,其中不能再嵌套注释如<!--错误的嵌套方式-->-->
是不允许的。 - 标签名、属性名建议使用小写字母:这是一种约定俗成的规范,小写字母在阅读和编写代码时更具一致性和可读性。同时,遵循这一规范也有助于与其他编程语言和框架的风格保持一致,减少因大小写不一致导致的潜在问题。
- 属性
- 属性必须有值,每个属性都为标签提供了额外的信息,而属性值就是这些信息的具体内容。例如
<img src="image.jpg" />
中的src
属性,其值image.jpg
指定了图片的来源路径。 - 属性值必须加引号,单双都行。这是为了明确区分属性值和其他XML语法元素,确保属性值能够被正确解析。例如
<a href='http://example.com'>链接</a>
和<a href="http://example.com">链接</a>
都是正确的写法。
- 属性必须有值,每个属性都为标签提供了额外的信息,而属性值就是这些信息的具体内容。例如
XML的约束(稍微了解)
将来我们主要就是根据XML约束中的规定来编写XML配置文件,而且会在我们编写XML的时候根据约束来提示我们编写,而XML约束主要包括DTD和Schema两种。
- DTD:文档类型定义(Document Type Definition),它是一种基于文本的简单约束方式,通过定义一系列的元素和属性规则,来规定XML文档的结构。DTD可以在XML文档内部直接定义,也可以外部引用。例如,一个简单的DTD定义可能如下:
xml
<!DOCTYPE students [
<!ELEMENT students (student+)>
<!ELEMENT student (name, age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]>
在这个DTD中,定义了<students>
元素可以包含一个或多个<student>
元素,<student>
元素必须包含<name>
和<age>
元素,并且<name>
和<age>
元素都包含可解析的文本数据。
- Schema :Schema约束要求我们一个XML文档中,所有标签,所有属性都必须在约束中有明确的定义。它相较于DTD更加灵活和强大,支持数据类型的定义、命名空间等高级特性。Schema通常以XML文档的形式存在,使用
<xsd:schema>
根元素来定义。例如:
xml
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="students">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="student" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
在这个Schema中,详细定义了<students>
、<student>
、<name>
和<age>
元素的结构和数据类型。<name>
元素被定义为字符串类型,<age>
元素被定义为整数类型,这使得对XML文档的验证更加严格和准确。
下面我们以web.xml的约束声明为例来做个说明:
xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
在这个web.xml
的声明中,xmlns
属性定义了默认的命名空间,用于区分不同的XML词汇表。xmlns:xsi
指定了用于处理XML Schema实例的命名空间。xsi:schemaLocation
属性则提供了XML Schema文档的位置,使得解析器能够根据指定的Schema对web.xml
进行验证。version
属性指定了web - app
的版本号。
1.2 DOM4J进行XML解析
1.2.1 DOM4J的使用步骤
- 导入jar包 :在项目中添加
dom4j.jar
包,这是使用DOM4J进行XML解析的基础。可以通过项目构建工具(如Maven或Gradle)从远程仓库下载,或者手动将dom4j.jar
添加到项目的类路径中。 - 创建解析器对象(SAXReader):SAXReader是DOM4J提供的用于解析XML文档的工具类。通过创建SAXReader对象,我们可以开始对XML文档进行解析操作。
java
SAXReader saxReader = new SAXReader();
- 解析xml获得Document对象 :使用SAXReader的
read
方法,传入要解析的XML文件的字节输入流,从而获取代表整个XML文档的Document对象。Document对象是DOM4J中对XML文档的内存表示,通过它可以方便地访问和操作文档中的各个元素。
java
InputStream inputStream = new FileInputStream("path/to/your/xml/file.xml");
Document document = saxReader.read(inputStream);
inputStream.close();
- 获取根节点RootElement :通过Document对象的
getRootElement
方法,获取XML文档的根元素。根元素是整个文档结构的起点,从根元素开始,我们可以进一步遍历和操作文档中的其他元素。
java
Element rootElement = document.getRootElement();
- 获取根节点下的子节点:根节点下通常包含多个子节点,我们可以通过不同的方法获取这些子节点。例如,可以获取所有子节点,或者获取指定标签名的子节点。
java
//获取所有子节点
List<Element> sonElementList = rootElement.elements();
//获取指定标签名的子节点
List<Element> sonElementList = rootElement.elements("标签名");
1.2.2 DOM4J的API介绍
- 创建SAXReader对象 :如前所述,通过
new
关键字创建SAXReader实例,开启对XML文档的解析之旅。
java
SAXReader saxReader = new SAXReader();
- 解析XML获取Document对象:需要传入要解析的XML文件的字节输入流。在实际应用中,要注意输入流的正确关闭,以释放资源。
java
InputStream inputStream = new FileInputStream("path/to/your/xml/file.xml");
Document document = saxReader.read(inputStream);
inputStream.close();
- 获取文档的根标签 :使用Document对象的
getRootElement
方法获取根标签。根标签是后续操作的基础,通过它可以深入到文档的各个层次。
java
Element rootElement = document.getRootElement();
- 获取标签的子标签 :
- 获取所有子标签 :
elements
方法返回一个包含所有子标签的列表,方便对同一层级的所有子元素进行批量处理。
- 获取所有子标签 :
java
List<Element> sonElementList = rootElement.elements();
- **获取指定标签名的子标签**:通过传入指定的标签名作为参数,可以精准地获取特定类型的子标签。这在处理具有复杂结构的XML文档时非常有用,能够快速定位到需要操作的元素。
java
List<Element> sonElementList = rootElement.elements("标签名");
- 获取标签体内的文本 :使用
getText
方法可以获取标签内部的文本内容。例如,如果有一个<name>张三</name>
标签,通过getText
方法可以获取到"张三"这个字符串。
java
String text = element.getText();
- 获取标签的某个属性的值 :利用
attributeValue
方法,传入属性名作为参数,即可获取指定属性的值。例如对于<img src="image.jpg" />
标签,通过element.attributeValue("src")
可以获取到image.jpg
这个图片路径。
java
String value = element.attributeValue("属性名");
二 Tomcat10
2.1 WEB服务器
Web服务器通常由硬件和软件共同构成。
- 硬件:电脑,提供服务供其它客户电脑访问。它是Web服务器运行的物理基础,其性能(如CPU处理能力、内存大小、硬盘读写速度等)会直接影响Web服务器的响应速度和并发处理能力。例如,在高并发访问的情况下,一台配置高性能CPU和大容量内存的服务器能够更稳定地处理大量请求,而不会出现卡顿或响应迟缓的情况。
- 软件:电脑上安装的服务器软件,安装后能提供服务给网络中的其他计算机,将本地文件映射成一个虚拟的url地址供网络中的其他人访问。服务器软件负责处理客户端的请求,解析请求内容,找到对应的本地资源,并将资源以合适的格式返回给客户端。不同的服务器软件在功能特性、性能表现、适用场景等方面存在差异,如Tomcat主要用于Java Web应用的部署和运行,而Nginx则在反向代理、负载均衡等方面表现出色。
常见的JavaWeb服务器:
- Tomcat(Apache):当前应用最广的JavaWeb服务器。它具有开源、免费、易于使用和扩展等优点,对Servlet和JSP规范的支持良好,适合各种规模的Java Web项目。无论是小型的个人项目,还是大型的企业级应用,都可以使用Tomcat作为服务器。
- Jetty:更轻量级、更灵活的servlet容器。它启动速度快,占用资源少,特别适合在一些对资源要求苛刻、需要快速部署和运行的场景中使用,如嵌入式系统中的Web服务、小型Web应用的快速开发和测试等。
- JBoss(Redhat红帽):支持JavaEE,应用比较广。它曾经是企业级Java应用开发中常用的服务器之一,提供了丰富的企业级功能,如EJB容器等。然而,随着SSH轻量级框架的兴起,JBoss在一些场景下的使用逐渐减少,但在某些特定的企业级环境中,仍然具有一定的应用价值。
- GlassFish(Orcale):Oracle开发JavaWeb服务器,应用不是很广。它虽然是Oracle公司推出的产品,但在市场上的占有率相对较低。不过,它对JavaEE规范的支持较为全面,在一些与Oracle技术栈紧密结合的项目中可能会被使用。
- Resin(Caucho):支持JavaEE,应用越来越广。Resin具有高性能、高稳定性的特点,在处理动态页面和并发请求方面表现出色,因此在一些对性能要求较高的Web应用中得到了越来越多的应用。
- Weblogic(Orcale):要钱的!支持JavaEE,适合大型项目。它是一款功能强大的企业级服务器,提供了丰富的管理工具和高级特性,如集群、负载均衡、高可用性等,适用于大型企业级应用的开发和部署。但其高昂的授权费用限制了它在一些小型项目和开源项目中的使用。
- Websphere(IBM):要钱的!支持JavaEE,适合大型项目。Websphere同样是一款面向大型企业的服务器产品,具备强大的功能和良好的稳定性,在金融、电信等对系统可靠性要求极高的行业中得到了广泛应用
2.2 Tomcat服务器
2.2.1 简介
Tomcat作为Apache软件基金会Jakarta项目的核心部分,汇聚了众多开发者的智慧与努力。其设计理念围绕着高效、稳定地运行Java Web应用展开,为开发者提供了便捷的Web开发与部署环境。由于它能够快速响应Servlet请求,出色地处理JSP页面动态内容,并且不断跟进最新的Servlet和JSP规范,使得基于Java的Web应用开发变得更加高效、灵活。同时,开源免费的特性让Tomcat深受广大Java开发者的喜爱,无论是个人开发者用于学习和实践,还是企业用于生产环境,都无需担心高昂的软件授权费用。
2.2.2 安装
版本
- 版本:企业中广泛使用的是8.0和9.0版本,它们经过长时间的使用和优化,稳定性和兼容性都得到了充分验证。目前较新的正式发布版本是Tomcat10.0,其在性能、功能以及对新规范的支持上都有显著提升。而Tomcat11仍处于测试阶段,虽然可能带来一些新特性,但在稳定性方面还需要进一步的检验。
- JAVAEE版本和Servlet版本号对应关系 :在Java Web开发中,了解不同版本的JAVAEE与Servlet版本之间的对应关系至关重要。随着Java技术的不断发展,新的规范和特性不断涌现,各个版本的Servlet和JAVAEE之间存在着紧密的联系。例如,在高版本的JAVAEE中,可能会引入新的功能和改进,而这些变化往往需要对应的Servlet版本来支持。详细对应关系可参考Jakarta EE Releases。
Servlet Version | EE Version |
---|---|
6.1 | Jakarta EE? |
6.0 | Jakarta EE 10 |
5.0 | Jakarta EE 9/9.1 |
4.0 | JAVA EE 8 |
3.1 | JAVA EE 7 |
3.1 | JAVA EE 7 |
3.0 | JAVAEE 6 |
- Tomcat版本和Servlet版本之间的对应关系:Tomcat的不同版本对Servlet版本的支持也有所不同。开发者在选择Tomcat版本时,需要根据项目所使用的Servlet版本以及对Java版本的要求来综合考虑。例如,若项目使用了Servlet 5.0规范,那么就需要选择Tomcat 10.0.x及以上版本。同时,不同版本的Tomcat对JDK的版本也有相应的要求,以确保能够充分发挥其性能和功能。
Servlet Version | **Tomcat ** Version | JDK Version |
---|---|---|
6.1 | 11.0.x | 17 and later |
6.0 | 10.1.x | 11 and later |
5.0 | 10.0.x (superseded) | 8 and later |
4.0 | 9.0.x | 8 and later |
3.1 | 8.5.x | 7 and later |
3.1 | 8.0.x (superseded) | 7 and later |
3.0 | 7.0.x (archived) | 6 and later (7 and later for WebSocket) |
下载
- Tomcat官方网站 :http://tomcat.apache.org/,这是获取Tomcat官方版本的权威渠道。在该网站上,不仅可以下载到不同版本的Tomcat,还能找到丰富的文档资源,包括安装指南、配置说明、版本更新日志等,方便开发者深入了解和使用Tomcat。
- 安装版:需要安装,安装过程相对复杂,可能会在系统中写入较多的配置信息和文件,并且在一些特定环境下可能会出现兼容性问题。此外,安装版在卸载时也可能会残留一些文件,因此一般不考虑使用。
- 解压版:直接解压缩使用,我们使用的版本。解压版的优势在于部署简单,灵活性高。只需将下载的压缩包解压到指定目录,即可快速完成Tomcat的部署。同时,解压版便于在不同环境之间迁移,例如在开发环境、测试环境和生产环境之间进行切换时,解压版能够更方便地进行配置和部署。
安装
- 正确安装JDK并配置JAVA_HOME :以JDK17为例,可在https://injdk.cn中下载各种版本的JDK。JDK是Java程序运行的基础,而配置JAVA_HOME环境变量则是为了让系统能够正确找到JDK的安装路径。在安装Tomcat之前,确保JDK已正确安装并配置好环境变量是至关重要的。若JDK安装或配置有误,Tomcat将无法正常启动。
- 解压tomcat到非中文无空格目录 :选择非中文无空格的目录是为了避免在启动Tomcat或部署应用时可能出现的路径解析问题。中文目录可能会因为编码问题导致Tomcat无法正确识别路径,而空格则可能会在命令行操作或配置文件中引发错误。例如,若将Tomcat解压到
C:\Program Files\Tomcat
目录下,在启动脚本中可能需要对路径进行特殊处理,否则可能会出现启动失败的情况。 - 点击bin/startup.bat启动 :运行
startup.bat
脚本是启动Tomcat的常见方式。在启动过程中,Tomcat会加载各种配置文件,初始化相关服务,并监听指定的端口。若启动过程中出现错误,可通过查看启动日志(位于logs目录下)来排查问题。例如,若端口被占用,启动日志中会提示相应的错误信息。 - 打开浏览器输入http://localhost:8080访问测试:通过在浏览器中输入该地址,可以验证Tomcat是否成功启动。若能看到Tomcat的默认欢迎页面,说明Tomcat已正常运行。若无法访问,可能是因为端口被占用、防火墙限制、Tomcat启动失败等原因。此时需要进一步排查问题,如检查端口占用情况、关闭防火墙或查看Tomcat的启动日志。
- 直接关闭窗口或者运行bin/shutdown.bat关闭tomcat :关闭窗口或运行
shutdown.bat
脚本都可以停止Tomcat服务。在关闭Tomcat之前,建议先确保所有正在运行的应用已正确停止,以避免数据丢失或文件损坏。同时,在生产环境中,建议使用shutdown.bat
脚本来关闭Tomcat,以确保关闭过程的规范性和安全性。 - 处理dos窗口日志中文乱码问题:修改conf/logging.properties,将所有的UTF - 8修改为GBK。在Windows系统中,默认的控制台编码可能与UTF - 8不兼容,导致日志中的中文出现乱码。将日志编码修改为GBK后,能够确保中文日志的正常显示,方便开发者查看和分析日志信息。
- 修改前 :
- 修改后 :
- 重启测试 :
2.3 Tomcat目录及测试
C:\Program4java\apache - tomcat - 10.1.7这个目录下直接包含Tomcat的bin目录,conf目录等,我们称之为Tomcat的安装目录或根目录。
- bin :该目录下存放的是二进制可执行文件。对于安装版,其中的
tomcat10.exe
和tomcat10w.exe
文件,前者用于在控制台下启动Tomcat,后者则会弹出GUI窗口启动Tomcat。而对于解压版,startup.bat
和shutdown.bat
文件则是启动和停止Tomcat的关键。startup.bat
启动Tomcat前,需先配置好JAVA_HOME环境变量,以确保能够找到JDK。这些可执行文件是与Tomcat交互的入口,通过它们,开发者可以方便地启动、停止和管理Tomcat服务。 - conf :这是一个极其重要的目录,其中有四个核心文件:
- server.xml :配置整个服务器信息。例如修改端口号。默认HTTP请求的端口号是8080,若该端口被占用,可通过修改
server.xml
文件中的<Connector>
标签的port
属性来指定其他可用端口。此外,还可以在该文件中配置虚拟主机、连接器等重要的服务器参数。 - tomcat - users.xml:存储tomcat用户的文件,保存着tomcat的用户名、密码以及用户角色信息。按照文件中的注释信息添加tomcat用户后,即可在Tomcat主页中进入Tomcat Manager页面。例如,添加如下用户配置:
- server.xml :配置整个服务器信息。例如修改端口号。默认HTTP请求的端口号是8080,若该端口被占用,可通过修改
html
<tomcat - users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema - instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat - users.xsd"
version="1.0">
<role rolename="admin - gui"/>
<role rolename="admin - script"/>
<role rolename="manager - gui"/>
<role rolename="manager - script"/>
<role rolename="manager - jmx"/>
<role rolename="manager - status"/>
<user username="admin"
password="admin"
roles="admin - gui,admin - script,manager - gui,manager - script,manager - jmx,manager - status"/>
</tomcat - users>
通过上述配置,创建了一个名为admin
,密码为admin
,拥有多种管理角色的用户,方便对Tomcat进行管理和监控。
-
web.xml :部署描述符文件,注册了大量MIME类型,即文档类型。这些MIME类型在客户端与服务器之间起着重要的作用,用于说明文档的类型。例如,当用户请求一个html网页时,服务器不仅会返回网页内容,还会告知客户端浏览器响应的文档是
text/html
类型。客户端浏览器根据这个MIME类型,就能正确地处理该文档,如在浏览器中显示html文件。而对于exe
文件,浏览器会根据其MIME类型,弹出下载窗口。 -
context.xml:对所有应用的统一配置,通常情况下我们不会对其进行配置。但在某些特定场景下,如需要对所有应用进行全局的资源配置、环境变量设置等,可通过修改该文件来实现。
- lib:Tomcat的类库,包含众多jar文件。这些jar文件是Tomcat运行和支持各种功能所必需的依赖库。若需要添加Tomcat依赖的jar文件,可将其放置在此目录中。同时,虽然也可以将应用依赖的jar文件放到这个目录中,使所有项目共享这些jar包,但这样会导致应用在迁移到其他Tomcat环境时,可能无法共享相同的jar包。因此,建议仅将Tomcat需要的jar包放置在此目录,而应用特定的依赖jar包,应通过其他方式进行管理。
- logs:该目录中存放的都是日志文件,记录了Tomcat启动和关闭的详细信息。若在启动Tomcat时出现错误,异常信息也会被记录在日志文件中。通过查看日志文件,开发者可以快速定位和解决问题。例如,在启动过程中出现的类加载错误、配置文件解析错误等,都能在日志文件中找到相关的错误提示。
- temp:存放Tomcat的临时文件,在停止Tomcat后,该目录下的文件可以被删除。Tomcat在运行过程中会生成一些临时文件,用于存储中间数据或缓存信息。这些临时文件在Tomcat停止后,通常不再需要,删除它们可以释放磁盘空间。
- webapps :存放web项目的目录,其中每个文件夹都是一个项目。若该目录下已存在目录,则大多是tomcat自带的项目。其中ROOT是一个特殊的项目,在地址栏中访问
http://127.0.0.1:8080
,未指定项目目录时,对应的就是ROOT项目。而访问http://localhost:8080/examples
,其中examples
就是项目名,即文件夹的名字。在实际开发中,我们将自己的Web项目部署到该目录下,即可通过相应的URL进行访问。 - work:运行时生成的文件,最终运行的文件都在此处。该目录下的文件是通过webapps中的项目生成的。在Tomcat运行过程中,当客户端访问一个JSP文件时,Tomcat会将JSP文件转换为Java文件,然后再编译Java文件生成class文件,这些生成的java和class文件都会存放到这个目录下。在某些情况下,如项目升级或调试时,可以删除这个目录下的内容,再次运行时会重新生成work目录。
- LICENSE:许可证文件,包含了Tomcat的使用许可条款和条件。通过阅读该文件,使用者可以了解自己在使用Tomcat过程中的权利和义务。
- NOTICE:说明文件,提供了关于Tomcat的一些重要说明信息,如贡献者名单、版本说明等。
2.4 WEB项目的标准结构
一个标准的可以用于发布的WEB项目标准结构如下:
- app:本应用根目录,作为整个Web项目的顶层目录,所有与该应用相关的文件和目录都存放在此。它是项目结构的基础,为项目提供了一个统一的组织框架。
- static :非必要目录,约定俗成的名字,一般在此处放静态资源(css、js、img)。静态资源是指在Web应用中不经常变动的文件,如样式表文件(css)、脚本文件(js)和图片文件(img)等。将它们放置在
static
目录下,便于管理和维护,同时也有利于提高网站的加载速度。例如,在HTML页面中引用这些静态资源时,可以通过相对路径轻松地访问到它们。 - WEB - INF :必要目录,必须叫WEB - INF,受保护的资源目录,浏览器通过url不可以直接访问的目录。该目录是Web项目的核心安全区域,存放着一些不应该被客户端直接访问的文件和配置信息。
- classes:必要目录,src下源代码,配置文件,编译后会在该目录下,web项目中如果没有源码,则该目录不会出现。这个目录包含了项目的所有编译后的类文件和配置文件。在开发过程中,Java源文件经过编译后生成的class文件会被放置在此目录下,同时,一些项目的配置文件,如数据库连接配置文件、Spring配置文件等也会存放在这里。
- lib :必要目录,项目依赖的jar编译后会出现在该目录下,web项目要是没有依赖任何jar,则该目录不会出现。在Web项目中,常常需要依赖各种第三方库来实现特定的功能,这些第三方库通常以jar文件的形式存在。将项目依赖的jar文件放置在
lib
目录下,Tomcat在运行项目时能够正确地加载这些依赖库,确保项目的正常运行。 - web.xml :必要文件,web项目的基本配置文件。在较新的版本中可以没有该文件,但在学习过程中还是需要该文件。
web.xml
文件用于配置Web应用的各种参数,如Servlet的映射、过滤器的配置、监听器的设置等。通过修改web.xml
文件,可以对Web应用的运行行为进行精细控制。
- index.html :非必要文件,
index.html
/index.htm
/index.jsp
为默认的欢迎页。当用户访问Web应用的根目录时,服务器会默认查找这些文件作为欢迎页进行展示。例如,当用户在浏览器中输入http://example.com
时,服务器会首先在Web应用的根目录下查找index.html
文件,若存在则将其返回给用户。
url的组成部分和项目中资源的对应关系 :
在这个关系图中,URL的各个部分与Web项目中的资源紧密相连。例如,http://localhost:8080/app/index.html
这个URL中,http
是协议部分,localhost
是服务器主机名,8080
是端口号,app
是项目的上下文路径,对应着webapps
目录下的app
文件夹,而index.html
则是该项目中的一个具体资源文件,位于app
文件夹下。通过这种对应关系,服务器能够准确地定位和返回用户请求的资源。
2.5 WEB项目部署的方式
方式1:直接将#### 方式1:直接将编译好的项目放在webapps目录下
这种方式最为直观和简单。当我们完成一个Web项目的开发与编译后,只需将整个项目文件夹直接拷贝到Tomcat安装目录下的webapps文件夹中 。Tomcat在启动时,会自动识别并部署该项目。例如,我们开发了一个名为"myProject"的Web项目,将其编译后的文件夹放置在webapps目录下后,通过访问http://localhost:8080/myProject
,就可以直接访问到该项目的内容。这种方式方便快捷,非常适合在开发和测试阶段使用,能够快速看到项目的运行效果。
方式2:将编译好的项目打成war包放在webapps目录下
把项目打成war(Web Application Archive)包是一种常见的项目分发和部署方式。我们可以使用Maven、Gradle等构建工具将项目打包成war包。打包完成后,将这个war包放置在Tomcat的webapps目录中。Tomcat启动时,会自动检测到这个war包,并将其解压,解压后的目录结构与直接放置在webapps目录下的项目结构一致。这种方式不仅方便了项目的传输和部署,而且war包的形式也有助于项目的版本管理。例如,当我们需要更新项目时,只需将新的war包替换原来的,Tomcat重启后即可生效。
方式3:将项目放在非webapps的其他目录下,在tomcat中通过配置文件指向app的实际磁盘路径
- 准备项目 :在磁盘的自定义目录上准备一个app,例如
D:\mywebapps\app
。这个目录下包含了完整的Web项目结构,包括静态资源、WEB - INF目录及其子目录和文件等。 - 配置Tomcat:在tomcat的conf下创建Catalina/localhost目录,并在该目录下准备一个app.xml文件。这个xml文件用于配置项目的访问路径和实际磁盘路径的映射关系。
xml
<!--
path: 项目的访问路径,也是项目的上下文路径,就是在浏览器中,输入的项目名称
docBase: 项目在磁盘中的实际路径
-->
<Context path="/app" docBase="D:\mywebapps\app" />
在上述配置中,path
属性指定了项目在浏览器中的访问路径,用户通过http://localhost:8080/app
来访问该项目;docBase
属性则指定了项目在磁盘中的实际存储位置。
- 启动与测试:配置完成后,启动tomcat,Tomcat会读取该配置文件,并根据配置将指定目录下的项目部署到服务器中。此时,我们就可以通过设定的访问路径进行访问测试。这种方式适用于一些特殊场景,例如需要将项目部署在特定的磁盘位置,或者多个Tomcat实例共享同一个项目目录的情况。
2.6 IDEA中开发并部署运行WEB项目
2.6.1 IDEA关联本地Tomcat
- 打开设置:可以在创建项目前设置本地tomcat,也可以在打开某个项目的状态下找到settings。通过点击菜单栏中的"File",然后选择"Settings"(在Mac系统中为"Preferences"),进入设置界面。
- 找到服务器设置:在设置界面中,找到"Build, Execution, Deployment"下的"Application Servers"选项。这里是管理和配置各种应用服务器的地方,我们要在这里添加本地的Tomcat服务器。
- 添加服务器:点击"Application Servers"选项右侧的"+"号,这是添加新服务器的入口。
- 选择Tomcat Server:在弹出的菜单中,选择"Tomcat Server"。IDEA支持多种服务器类型,我们选择Tomcat来进行Web项目的部署。
- 指定安装目录:在弹出的窗口中,选择tomcat的安装目录。通过点击"Configure"按钮,浏览到本地Tomcat的安装路径,例如"C:\Program Files\Apache Software Foundation\Tomcat 10.0",然后点击"OK"。
- 完成关联:点击"OK"后,IDEA会自动检测Tomcat的相关信息,并完成与本地Tomcat的关联。此时,在"Application Servers"列表中,就可以看到已关联的Tomcat服务器。
2.6.2 IDEA创建web工程
- 创建空项目(可选):推荐先创建一个空项目,这样可以在一个空项目下同时存在多个modules,避免后续来回切换之前的项目。在IDEA的欢迎界面中,点击"Create New Project",然后在弹出的窗口中选择"Empty Project",输入项目名称和保存路径,点击"Finish"即可创建一个空项目。
- 检查项目设置:创建项目后,需要检查项目的SDK、语法版本,以及项目编译后的输出目录。点击菜单栏中的"File",选择"Project Structure",在弹出的窗口中,可以在"Project"选项卡中设置项目的SDK和语言级别;在"Modules"选项卡中,可以设置项目的输出目录等信息。确保这些设置符合项目的需求,例如选择合适的JDK版本,设置正确的输出目录为"out/production/项目名称"。
- 创建普通Java项目:在项目中创建一个普通的Java项目作为基础。在项目结构面板中,右键点击项目名称,选择"New" -> "Module",在弹出的窗口中选择"Java",按照向导提示设置项目名称、模块名称等信息,点击"Finish"创建Java项目。
- 添加Tomcat依赖:创建完Java项目后,为项目添加Tomcat依赖。在项目结构面板中,右键点击项目名称,选择"Open Module Settings",在弹出的窗口中选择"Dependencies"选项卡,点击右侧的"+"号,选择"Library",在弹出的窗口中找到"Tomcat"相关的库,点击"OK"完成添加。
- 添加Web框架支持:选择modules,添加框架支持。在项目结构面板中,右键点击模块名称,选择"Add Framework Support",在弹出的窗口中选择"Web Application",注意选择合适的Version,勾选"Create web.xml",点击"OK"。此时,IDEA会自动为项目添加Web项目所需的目录结构和配置文件。
- 替换默认文件:删除自动生成的index.jsp,替换为index.html。在项目的web目录下,删除index.jsp文件,然后创建一个新的index.html文件,可以在其中编写简单的HTML内容,例如:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF - 8">
<title>My Web Project</title>
</head>
<body>
<h1>Welcome to my web project!</h1>
</body>
</html>
- 处理配置文件 :
- 创建资源目录:在工程下创建resources目录,专门用于存放配置文件。虽然都放在src下也行,但单独存放可以尽量避免文件集中存放造成的混乱。在项目结构面板中,右键点击项目名称,选择"New" -> "Directory",创建名为"resources"的目录。
- 标记目录为资源目录:不标记的话该目录不参与编译。右键点击"resources"目录,选择"Mark Directory as" -> "Resources Root",标记完成后,该目录会显示为蓝色,表明它已被识别为资源目录。
- 处理依赖jar包问题 :
- 创建lib目录:在WEB - INF下创建lib目录,必须在WEB - INF下,且目录名必须叫lib。在项目结构面板中,找到WEB - INF目录,右键点击它,选择"New" -> "Directory",创建名为"lib"的目录。
- 添加jar文件:复制所需的jar文件进入lib目录。例如,如果项目需要使用数据库连接的相关库,将对应的JDBC驱动jar文件复制到lib目录中。
- 添加依赖:将lib目录添加为当前项目的依赖。在项目结构面板中,右键点击模块名称,选择"Open Module Settings",在弹出的窗口中选择"Dependencies"选项卡,点击右侧的"+"号,选择"Module Dependency",在弹出的窗口中找到lib目录对应的依赖项,点击"OK"。后续可以用Maven统一解决依赖管理问题。
- 选择依赖级别:环境级别推荐选择module级别,降低对其他项目的影响,name可以空着不写。在添加依赖的过程中,选择"Module"级别,这样该依赖只对当前模块生效,不会影响到项目中的其他模块。
- 查看依赖:可以在"Dependencies"选项卡中查看当前项目有哪些环境依赖。这里会列出所有已添加的依赖项,包括Tomcat依赖、lib目录下的依赖等。同时,也可以在此通过"-"号解除不需要的依赖。
2.6.3 IDEA部署 - 运行web项目
- 检查项目识别与配置 :
- 检查模块识别:检查idea是否识别modules为web项目并存在将项目构建成发布结构的配置。查看工程目录下,web目录是否有特殊的识别标记,例如是否显示为蓝色的文件夹图标,表明它已被正确识别为Web资源目录。
- 检查artifacts配置 :以及artifacts下,有没有对应
_war_exploded
,如果没有,就点击"+"号添加。在IDEA的右侧边栏中,找到"Build" -> "Artifacts",确保其中有与项目对应的_war_exploded
条目。如果没有,点击"+"号,选择"Web Application: Exploded" -> "From Modules",按照向导提示进行配置,创建_war_exploded
条目。
- 打开运行配置界面:点击IDEA右上角的向下箭头,出现"Edit Configurations"选项,点击它进入运行配置界面。
- 添加本地tomcat服务器:在运行配置界面中,点击左上角的"+"号,添加本地tomcat服务器。选择"Tomcat Server" -> "Local",IDEA会自动检测并列出已关联的Tomcat服务器。
- 选择Tomcat服务器:因为IDEA只关联了一个Tomcat,红色部分就只有一个Tomcat可选,点击选择该Tomcat服务器。
- 配置部署信息 :
- 添加artifact :选择"Deployment",通过"+"添加要部署到Tomcat中的artifact。在弹出的窗口中,选择之前创建的
_war_exploded
条目,点击"OK"。 - 设置上下文路径 :
applicationContext
中是默认的项目上下文路径,也就是url中需要输入的路径,这里可以自己定义,可以和工程名称不一样,也可以不写,但要保留"/",我们这里暂时就用默认的。例如,如果项目名称为"myWebApp",默认的上下文路径为"/myWebApp",可以根据实际需求修改为"/app"等。
- 添加artifact :选择"Deployment",通过"+"添加要部署到Tomcat中的artifact。在弹出的窗口中,选择之前创建的
- 配置服务器启动选项:点击"apply"应用后,回到"Server"部分。"After Launch"是配置启动成功后,是否默认自动打开浏览器并输入URL中的地址,"HTTP port"是Http连接器目前占用的端口号。可以根据需要勾选"Open browser",并设置启动后要访问的URL路径;同时,确保"HTTP port"设置正确,默认为8080,如果该端口被占用,可以修改为其他可用端口。
- 启动与测试 :
- 启动项目:点击"OK"后,通过点击绿色箭头(正常运行模式)或"小虫子"(debug运行模式)启动项目。在启动过程中,IDEA会在控制台输出项目的启动日志。
- 查看日志:启动后,查看日志状态是否有异常。如果出现错误信息,需要根据日志提示进行排查和解决。例如,如果提示找不到某个类或资源,可能是依赖没有正确添加或路径配置有误。
- 浏览器访问:如果启动成功,浏览器会自动打开并自动访问index.html欢迎页。如果没有自动打开浏览器,可以手动在浏览器中输入设置的URL地址,查看项目是否正常运行。
工程结构和可以发布的项目结构之间的目录对应关系 :
在这个对应关系中,工程结构中的src目录下的Java源文件和资源文件,经过编译后会对应到发布结构中的classes目录;工程结构中的web目录下的静态资源和WEB - INF目录及其子目录和文件,会直接对应到发布结构中的相应位置。例如,工程结构中web目录下的css文件,在发布结构中仍然位于web目录下的相同位置;工程结构中src/main/resources目录下的配置文件,在发布结构中会位于classes目录下。
IDEA部署并运行项目的原理:
- 创建Tomcat副本:IDEA并没有直接将编译好的项目放入tomcat的webapps中,而是根据关联的tomcat,创建了一个tomcat副本。这个副本包含了与当前项目相关的配置信息,用于在本地环境中模拟Tomcat的运行。
- 项目部署到副本:IDEA将项目部署到这个副本中,通过一系列的配置和文件复制操作,确保项目能够在Tomcat副本中正确运行。例如,将项目的编译后的文件、依赖的jar包等放置到Tomcat副本的相应目录中。
- 副本配置位置 :IDEA的tomcat副本在
C:\用户\当前用户\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\
中,这个目录是IDEA在本地系统中创建的用于存放Tomcat副本的位置。 - 副本结构特点:IDEA的tomcat副本并不是一个完整的tomcat,副本里只是准备了和当前项目相关的配置文件而已。它主要包含了项目的部署配置、服务器启动参数等信息,通过这些配置文件来指导Tomcat如何运行项目。
- 启动方式:IDEA启动tomcat时,是让本地tomcat程序按照tomcat副本里的配置文件运行。这样,就实现了在IDEA环境中对Tomcat服务器的控制和项目的部署运行。例如,通过修改Tomcat副本中的配置文件,可以调整项目的上下文路径、端口号等参数。
- 部署模式 :IDEA的tomcat副本部署项目的模式是通过
conf/Catalina/localhost/*.xml
配置文件的形式实现项目部署的。在这个配置文件中,指定了项目的上下文路径、实际磁盘路径等信息,与前面提到的Tomcat的第三种部署方式类似。例如,在conf/Catalina/localhost/myWebApp.xml
文件中,配置了<Context path="/myWebApp" docBase="C:\Users\当前用户\IdeaProjects\myWebApp\out\production\myWebApp_war_exploded" />
,这样Tomcat在启动时就会根据这个配置文件来部署项目。
三 HTTP协议
3.1 HTTP简介
HTTP超文本传输协议 (HTTP - Hyper Text transfer protocol),作为应用层的核心协议之一,以其面向对象的设计理念,构建了浏览器与万维网服务器之间沟通的桥梁。自1990年诞生以来,HTTP凭借其简捷、快速的特性,迅速在分布式超媒体信息系统中得到广泛应用。它详细规定了客户端与服务器之间的通信规则,使得不同的设备和系统能够在网络环境中实现无缝的数据交互。在日常的网络浏览中,当我们在浏览器中输入一个网址并按下回车键时,浏览器会按照HTTP协议的规定,将请求信息发送给服务器;服务器接收到请求后,也会依据HTTP协议的要求,对请求进行解析和处理,并将响应结果返回给浏览器。而在这个过程中,客户端与服务端通信时传输的内容,我们称之为报文 。HTTP协议的核心任务就是规定报文的格式 ,确保请求和响应能够被正确地理解和处理。实际上,我们需要深入学习的就是这两种报文:客户端发送给服务器的称为"请求报文" ,服务器发送给客户端的称为"响应报文"。
3.1.1 发展历程
HTTP/0.9
蒂姆·伯纳斯·李这位英国计算机科学家,在1989年开创性地创建了单行HTTP协议。在那个早期阶段,该协议的功能相对简单,仅仅能够返回一个网页。到了1991年,这个协议被正式命名为HTTP/0.9。虽然它的功能有限,但却是HTTP协议发展历程中的重要起点,为后续版本的演进奠定了基础。
HTTP/1.0
1996年,HTTP/1.0正式发布。与前身相比,这一版本的规范得到了显著的扩展。它引入了对三种请求方法的支持,即GET
、HEAD
和POST
。这使得客户端与服务器之间的交互更加多样化和灵活。例如,GET
方法常用于从服务器获取资源,POST
方法则常用于向服务器提交数据。
HTTP/1.0相对于HTTP/0.9的改进是多方面的:
- 版本标识:每个请求都附加了HTTP版本,这使得服务器和客户端能够明确知晓所使用的协议版本,有助于在后续的版本升级和兼容性处理中进行判断和调整。
- 状态代码 :在响应开始时发送状态代码,如常见的200表示请求成功,404表示资源未找到等。这些状态代码为客户端
提供了关于请求处理结果的清晰反馈,方便客户端根据不同的状态采取相应的措施。例如,当浏览器接收到404状态码时,会向用户展示"页面未找到"的提示信息。 - 报文头 :请求和响应都包含HTTP报文头。报文头中携带了丰富的信息,如请求的来源、客户端的类型、所支持的内容类型等。这些信息对于服务器和客户端进行交互和处理请求至关重要。例如,服务器可以根据客户端发送的
Accept
报文头字段,了解客户端支持的内容类型,从而返回相应格式的资源。 - 内容类型扩展:能够传输HTML文件以外的文档,如图片、文本文件等。这极大地丰富了Web的内容形式,使得Web应用不再局限于简单的HTML页面展示,为后来多媒体内容在Web上的广泛传播奠定了基础。
然而,需要注意的是,HTTP/1.0并非官方标准,这也为后续版本的进一步完善留下了空间。
HTTP/1.1
HTTP的第一个标准化版本HTTP/1.1(RFC 2068)于1997年初发布,它进一步拓展了请求方法的种类,支持七种请求方法,包括OPTIONS
、GET
、HEAD
、POST
、PUT
、DELETE
和TRACE
。这些新增的请求方法为开发者提供了更多控制资源的手段。例如,PUT
方法可用于向服务器上传资源,DELETE
方法用于删除服务器上的资源。
HTTP/1.1在HTTP 1.0的基础上进行了多方面的增强:
- 虚拟主机:允许从单个IP地址提供多个域。这一特性使得在同一台服务器上可以部署多个不同域名的网站,提高了服务器资源的利用率。例如,一家网络服务提供商可以在一台服务器上为多个客户提供网站托管服务,每个客户的网站对应不同的域名,但都通过同一台服务器的IP地址进行访问。
- 持久连接和流水线连接:持久连接允许Web浏览器通过单个持久连接发送多个请求,而无需为每个请求都建立新的连接,减少了连接建立的开销和延迟。流水线连接则进一步优化了请求的发送方式,允许在同一个连接上连续发送多个请求,而无需等待前一个请求的响应。这两种连接方式显著提高了Web应用的性能和响应速度,尤其在加载包含多个资源的页面时效果明显。例如,当加载一个包含多个图片、CSS文件和JavaScript文件的网页时,通过持久连接和流水线连接,浏览器可以更快地获取这些资源,减少了页面加载的时间。
- 缓存支持:引入了更完善的缓存机制,允许服务器和客户端对资源进行缓存。当客户端再次请求相同的资源时,如果该资源在缓存有效期内且未被修改,服务器可以直接返回缓存的资源,节省了带宽并使响应速度更快。例如,用户频繁访问的网页中的一些静态资源,如图标、CSS样式表等,可以被缓存到客户端,下次访问时无需再次从服务器下载,从而加快了页面的加载速度。
在接下来的15年左右时间里,HTTP/1.1保持了非常稳定的状态,成为了Web应用中广泛使用的协议版本。同时,在此期间,HTTPS(安全超文本传输协议)应运而生。HTTPS是HTTP的安全版本,它使用SSL/TLS进行安全加密通信,有效地保护了数据在传输过程中的安全性,防止数据被窃取或篡改。在如今的网络环境中,尤其是涉及用户敏感信息的场景,如在线支付、登录验证等,HTTPS已经成为了标准的通信协议。
HTTP/2
2015年,IETF发布了HTTP/2协议。HTTP/2旨在解决HTTP/1.1在性能和效率方面的一些瓶颈,以适应日益增长的Web应用需求。它带来了一系列具有革命性的改进:
- 多路复用:HTTP/2允许同时发送多个请求和响应,而不是像HTTP/1.1一样只能一个一个地处理。这意味着在同一时间内,客户端可以向服务器发送多个请求,服务器也可以同时处理并返回多个响应。这种机制极大地提高了网络吞吐量,减少了延迟。例如,在加载一个包含大量图片、脚本和样式文件的复杂网页时,HTTP/2能够同时请求这些资源,而不需要像HTTP/1.1那样按顺序依次请求,从而大大缩短了页面的加载时间。
- 二进制传输:与HTTP/1.1使用的文本协议不同,HTTP/2采用了二进制协议。二进制协议在解析和传输数据时更加高效,能够减少传输过程中的开销和延迟。文本协议需要对文本进行解析和编码,而二进制协议可以直接处理二进制数据,提高了数据处理的速度和准确性。
- 头部压缩:HTTP/2使用HPACK算法对HTTP头部进行压缩。在HTTP/1.1中,每次请求和响应都会携带大量的头部信息,这些信息在多次请求中可能会有重复,导致带宽的浪费。HTTP/2通过HPACK算法对头部进行压缩,减少了头部传输的数据量,从而降低了网络延迟。例如,对于频繁请求的同一网站的资源,头部中的一些信息,如用户代理、接受的内容类型等,在多次请求中基本不变,通过头部压缩可以显著减少这些重复信息的传输。
- 服务器推送:支持服务器推送功能,允许服务器在客户端请求之前主动推送资源。例如,当客户端请求一个HTML页面时,服务器可以根据页面的内容分析,提前推送相关的CSS文件、JavaScript文件和图片等资源,这样客户端在解析HTML页面时就可以直接使用这些已推送的资源,无需再发起额外的请求,进一步提高了页面的加载速度。
- 改进的安全性:HTTP/2默认使用TLS(Transport Layer Security)加密传输数据,提高了数据传输的安全性。这使得在使用HTTP/2协议时,数据在网络传输过程中更加难以被窃取或篡改,为用户提供了更安全的网络环境。
- 兼容HTTP/1.1:HTTP/2可以与HTTP/1.1共存,服务器可以同时支持HTTP/1.1和HTTP/2。如果客户端不支持HTTP/2,服务器可以自动回退到HTTP/1.1进行通信。这种兼容性确保了在不同客户端环境下,Web应用都能够正常运行,同时也为HTTP/2的逐步推广和应用提供了便利。
HTTP/3
2021年5月27日,HTTP/3正式发布。这是继HTTP/1.1和HTTP/2之后的又一次重大修订,旨在进一步提升Web性能和安全性。与之前的版本不同,HTTP/3没有使用TCP,而是采用了谷歌在2012年开发的新协议QUIC(Quick UDP Internet Connections)。
QUIC协议基于UDP协议构建,但在可靠性和性能方面进行了大量的优化。它通过在用户空间实现连接管理、拥塞控制等功能,能够更快速地建立连接,减少延迟,并在网络不稳定的情况下保持更好的性能。例如,在移动网络环境中,由于网络信号的波动和变化,TCP连接可能会频繁出现丢包和重传的情况,导致性能下降。而QUIC协议通过其独特的设计,能够更好地应对这种情况,提供更稳定和高效的网络传输。
HTTP/3带来的革命性变化,使其在Web性能和安全性方面都有了显著的提升。目前,谷歌云、Cloudflare和Fastly等一些知名的云服务提供商已经支持HTTP/3。在浏览器方面,Chrome、Firefox、Edge、Opera和一些移动浏览器也陆续加入了对HTTP/3的支持行列。随着越来越多的服务器和浏览器支持HTTP/3,它有望在未来成为Web通信的主流协议,为用户带来更快速、更安全的网络体验。
3.1.2 HTTP协议的会话方式
浏览器与服务器之间的通信过程遵循一个特定的流程,主要经历以下四个步骤:
- 建立连接:浏览器通过指定的IP地址和端口号与服务器建立TCP连接。这一步就像是在浏览器和服务器之间搭建了一条通信的通道,为后续的数据传输做好准备。在这个过程中,浏览器会向服务器发送一个SYN(同步)数据包,服务器收到后会返回一个SYN + ACK(同步确认)数据包,最后浏览器再发送一个ACK(确认)数据包,完成三次握手,从而建立起可靠的TCP连接。
- 发送请求:连接建立后,浏览器会根据用户的操作,如在地址栏输入网址、点击链接或提交表单等,生成HTTP请求报文,并通过建立好的TCP连接将请求发送给服务器。请求报文中包含了请求方法(如GET、POST等)、请求的资源路径、请求头信息以及可能的请求体内容。例如,当用户在浏览器中输入一个网址并按下回车键时,浏览器会生成一个GET请求,请求服务器返回该网址对应的网页资源。
- 服务器响应:服务器接收到浏览器的请求后,会对请求进行解析和处理。服务器会根据请求的资源路径找到对应的资源,并生成HTTP响应报文。响应报文中包含了响应状态码、响应头信息和响应体内容。响应状态码表示请求的处理结果,如200表示请求成功,404表示资源未找到等。响应头信息包含了关于响应的一些元数据,如内容类型、缓存控制等。响应体内容则是服务器返回给浏览器的实际数据,可能是HTML页面、图片、JSON数据等。例如,如果请求的是一个HTML网页,服务器会将该网页的内容作为响应体返回给浏览器。
- 关闭连接 :浏览器收到服务器的响应后,会对响应进行解析和处理。如果响应状态码为200且响应体内容是HTML页面,浏览器会对HTML页面进行渲染,展示给用户。在完成数据传输后,浏览器和服务器会关闭TCP连接,释放资源。不过,在HTTP/1.1及以上版本中,通过设置
Connection: keep - alive
头字段,可以保持连接的持久性,以便在后续的请求中复用该连接,减少连接建立的开销。
浏览器与WEB服务器之间的连接具有短暂性的特点,每次连接通常只处理一个请求和响应。对于每一个页面的访问,浏览器与WEB服务器都要建立一次单独的连接。这种连接方式虽然在一定程度上增加了连接建立的开销,但也保证了连接的独立性和安全性。同时,浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应对,这使得每个请求和响应都能够被独立处理,提高了系统的灵活性和可扩展性。例如,当用户在浏览器中快速点击多个链接时,每个链接的请求和响应都是独立进行的,互不干扰。
3.1.3 HTTP1.0和HTTP1.1的区别
在HTTP1.0版本中,浏览器的连接机制相对简单。当浏览器请求一个带有图片的网页时,由于当时的协议限制,在下载图片时会与服务器之间开启一个新的连接。这意味着每获取一个新的资源(如图片、CSS文件、JavaScript文件等),都需要重新建立一次TCP连接。而建立TCP连接需要进行三次握手等一系列操作,这无疑增加了网络延迟和资源消耗。例如,一个网页包含10张图片,那么在HTTP1.0下,浏览器可能需要与服务器建立10次新的连接来下载这些图片,这会导致页面加载速度明显变慢。
然而,在HTTP1.1版本中,引入了持久连接(Persistent Connection)的概念。这一特性允许浏览器在拿到当前请求对应的全部资源后再断开连接。也就是说,在一次TCP连接建立后,浏览器可以通过这个连接发送多个请求,获取多个资源,而不需要为每个资源都重新建立连接。这大大提高了资源的获取效率,减少了连接建立的开销和延迟。例如,同样是包含10张图片的网页,在HTTP1.1下,浏览器只需建立一次TCP连接,就可以通过这个连接依次请求并下载所有的图片,从而显著加快了页面的加载速度。
此外,HTTP1.1还支持流水线连接(Pipelining)。在流水线连接中,浏览器可以在未收到前一个请求的响应时,就继续发送下一个请求。这使得请求的发送更加高效,进一步提高了网络吞吐量。例如,浏览器可以在发送第一个图片请求后,不等服务器返回响应,就接着发送第二个图片请求,这样可以充分利用网络带宽,减少等待时间。
总的来说,HTTP1.1相对于HTTP1.0在连接管理和资源获取效率方面有了显著的提升,这也是为什么HTTP1.1在很长一段时间内成为了Web应用中广泛使用的协议版本。
3.1.4 在浏览器中通过F12工具抓取请求响应报文包
几乎所有的PC端浏览器都支持了F12开发者工具,尽管不同的浏览器在工具显示的窗口布局和功能细节上可能存在差异,但它们的核心功能都是相似的,即帮助开发者分析和调试Web应用。
以常见的Chrome浏览器为例,当我们在浏览器中打开一个网页后,按下F12键,会弹出开发者工具窗口。在这个窗口中,有多个选项卡,其中"Network"选项卡是用于抓取请求响应报文包的主要区域。当我们在浏览器中进行各种操作,如刷新页面、点击链接、提交表单等时,"Network"选项卡会实时记录所有的网络请求。
在"Network"选项卡中,我们可以看到每个请求的详细信息,包括请求的URL、请求方法(GET、POST等)、响应状态码、响应时间、请求头和响应头信息以及请求体和响应体内容等。通过这些信息,开发者可以深入了解浏览器与服务器之间的通信过程,分析请求和响应是否正常,查找可能存在的性能问题或错误。例如,如果发现某个请求的响应时间过长,可以通过查看请求头和响应头信息,分析是否存在网络延迟、服务器负载过高或资源未正确缓存等问题。
不同浏览器的F12开发者工具在界面设计上可能有所不同。例如,Firefox浏览器的开发者工具在布局上与Chrome略有差异,但同样提供了丰富的功能来分析网络请求。在Firefox中,"Network"面板同样可以展示请求的详细信息,并且还提供了一些独特的功能,如性能分析图表,帮助开发者更直观地了解网络请求的性能情况。
IE浏览器的F12开发者工具也具备类似的功能,但在操作方式和显示效果上可能会让习惯了其他浏览器的开发者感到有些不同。然而,无论哪种浏览器,通过F12工具抓取请求响应报文包都是进行Web开发和调试的重要手段之一,它能够帮助开发者快速定位和解决问题,优化Web应用的性能和用户体验。
3.2 请求和响应报文
3.2.1 报文的格式
HTTP报文在结构上主要分为报文首部和报文主体两大部分,两者之间通过一个空行隔开。这种结构设计使得报文的信息组织清晰,便于解析和处理。
报文首部是报文的重要组成部分,它包含了关于请求或响应的各种元信息。这些信息对于服务器和客户端理解报文的意图、处理方式以及内容类型等至关重要。报文首部又可以进一步细分为"行"和"头"。
"行"部分主要包括请求行(在请求报文中)或响应行(在响应报文中)。请求行用于描述请求的基本信息,如请求方法、请求的资源路径以及使用的HTTP协议版本。例如,一个常见的请求行可能是GET /index.html HTTP/1.1
,其中GET
是请求方法,表示从服务器获取资源;/index.html
是请求的资源路径,指定了要获取的具体文件;HTTP/1.1
则表示使用的HTTP协议版本。响应行则用于表示响应的状态信息,如HTTP/1.1 200 OK
,其中HTTP/1.1
是协议版本,200
是响应状态码,表示请求成功,OK
是对状态码的文本描述。
"头"部分由一系列的键值对组成,每个键值对称为一个首部字段。这些首部字段提供了更多关于请求或响应的详细信息。例如,在请求报文中,User - Agent
首部字段用于标识客户端的类型和版本,服务器可以根据这个信息对不同的客户端进行针对性的处理;Accept
首部字段用于告知服务器客户端能够接受的内容类型,服务器会根据这个信息返回相应格式的资源。在响应报文中,Content - Type
首部字段用于指定响应体的内容类型,如text/html
表示响应体是HTML格式的文档,application/json
表示响应体是JSON格式的数据;Content - Length
首部字段用于指定响应体的长度,客户端可以根据这个信息正确地接收和处理响应体内容。
报文主体则包含了请求或响应的实际数据。在请求报文中,只有当请求方法为POST等需要发送数据的方法时,才会有请求体,例如在提交表单时,表单中的数据会作为请求体发送给服务器。在响应报文中,响应体通常包含了服务器返回给客户端的实际内容,如HTML页面、图片、JSON数据等。例如,当我们请求一个HTML网页时,服务器返回的HTML代码就是响应体的内容,浏览器会对这些内容进行解析和渲染,展示给用户。
下面通过一个简单的图示来更直观地展示报文的格式:
报文首部
请求行/响应行
首部字段1: 值1
首部字段2: 值2
...
(空行)
报文主体
实际数据内容
这种清晰的结构设计使得HTTP报文在网络传输中能够准确地传达信息,并且方便服务器和客户端进行解析和处理。无论是在简单的Web浏览场景中,还是在复杂的Web应用开发中,理解和掌握HTTP报文的格式都是至关重要的。
3.2.2 请求报文
请求报文是客户端发送给服务端的信息载体,其格式具有特定的规范,主要由以下几个部分组成:
-
请求首行(请求行) :格式为
GET/POST 资源路径?参数 HTTP/1.1
。请求方法指定了客户端对服务器资源的操作类型,常见的有GET
和POST
。GET
方法常用于从服务器获取资源,它将请求参数附加在URL的查询字符串中,例如GET /products?category=electronics&page=1 HTTP/1.1
,其中/products
是资源路径,category=electronics&page=1
是请求参数。POST
方法通常用于向服务器提交数据,如用户注册信息、表单数据等,这些数据会放在请求体中。资源路径指定了要访问的服务器资源的具体位置,而HTTP版本则表明了请求所遵循的协议版本。 -
请求头 :由一系列的键值对组成,如
User - Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
。常见的请求头字段有很多,User - Agent
用于标识客户端的浏览器类型、操作系统等信息,服务器可以据此为不同的客户端提供适配的内容。Accept
字段告诉服务器客户端能够接受的响应内容类型,例如Accept: text/html,application/xhtml+xml,application/xml;q = 0.9,image/avif,image/webp,image/apng,*/*;q = 0.8
,表示客户端优先接受HTML、XHTML、XML等格式的内容。Accept - Encoding
字段指定客户端支持的编码格式,如gzip
、deflate
等,服务器可以根据此信息对响应内容进行压缩,以减少传输数据量。Accept - Language
字段表示客户端偏好的语言,服务器可以据此返回对应语言的内容。Cookie
字段用于在客户端和服务器之间传递会话信息,服务器可以通过读取Cookie
来识别用户身份、跟踪用户会话等。 -
空行:在请求头之后,需要有一个空行,用于分隔请求头和请求体。这个空行是请求报文格式的重要组成部分,它明确标识了请求头部分的结束,为后续解析请求体做好准备。
-
请求体 :只有当请求方法为
POST
、PUT
等需要向服务器发送数据的方法时才会有请求体。例如,在用户注册时,注册表单中的用户名、密码、邮箱等信息会放在请求体中发送给服务器。请求体的格式可以是多种形式,常见的有application/x - www - form - urlencoded
格式,这种格式将表单数据以键值对的形式进行编码,例如username=john&password=123456&email=john@example.com
。如果是上传文件,可能会使用multipart/form - data
格式,这种格式可以处理多个部分的数据,包括文件内容和其他表单数据。对于JSON格式的数据,请求体可能是一个符合JSON语法的字符串,例如{"name": "Alice", "age": 30, "city": "New York"}
。
下面是一个完整的请求报文示例:
POST /register HTTP/1.1
Host: example.com
User - Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q = 0.9,image/avif,image/webp,image/apng,*/*;q = 0.8
Accept - Encoding: gzip, deflate
Accept - Language: en - US,en;q = 0.9
Cookie: session_id=1234567890abcdef
Content - Type: application/x - www - form - urlencoded
Content - Length: 36
username=john&password=123456&email=john@example.com
在这个示例中,请求首行表明这是一个POST
请求,要访问的资源路径是/register
,使用的HTTP版本是1.1
。请求头部分包含了客户端的各种信息,如浏览器类型、可接受的内容类型、编码方式、语言偏好、会话Cookie
等。空行之后是请求体,包含了用户注册的表单数据。
3.2.3 响应报文
响应报文是服务器对客户端请求的反馈,它的格式同样遵循特定的规则,由以下关键部分构成:
-
响应首行(响应行) :其格式为
HTTP/1.1 状态码 状态码描述
。例如HTTP/1.1 200 OK
,其中HTTP/1.1
代表服务器使用的HTTP协议版本。状态码是一个三位数字,用于表示请求处理的结果。常见的状态码有200
,表示请求成功,服务器正常返回了客户端所请求的资源;404
表示服务器未找到客户端所请求的资源;500
表示服务器内部发生错误,无法完成请求处理。状态码描述是对状态码的文本解释,方便开发人员和用户快速理解请求的处理情况。 -
响应头 :由多个键值对组成,例如
Content - Type: text/html; charset=UTF - 8
。Content - Type
指定了响应内容的类型,在此例中表示响应内容是HTML格式,并且字符编码为UTF - 8,这确保了客户端能够正确解析和显示响应内容。Content - Length
用于告知客户端响应体的长度,例如Content - Length: 1234
,客户端可以根据这个长度准确地接收和处理响应体数据。Set - Cookie
用于在客户端设置Cookie
,例如Set - Cookie: session_id=abcdef; expires=Thu, 31 Dec 2025 23:59:59 UTC; path=/
,服务器通过这个响应头将Cookie
信息发送给客户端,客户端在后续的请求中会携带这个Cookie
,以便服务器识别用户会话等信息。Cache - Control
用于控制缓存行为,例如Cache - Control: no - cache
,表示不允许客户端缓存响应内容,每次请求都需要从服务器重新获取。 -
空行:在响应头和响应体之间,同样需要一个空行作为分隔。这个空行明确划分了响应头部分的结束,使得服务器能够清晰地区分响应头信息和实际的响应数据。
-
响应体 :包含了服务器返回给客户端的实际内容。如果请求的是一个HTML网页,响应体就是完整的HTML代码,客户端的浏览器会对这些代码进行解析和渲染,展示出对应的网页内容。若请求的是JSON格式的数据,响应体则是符合JSON语法的字符串,例如
{"data": [{"id": 1, "name": "Product 1"}, {"id": 2, "name": "Product 2"}]}
,客户端可以根据这个JSON数据进行相应的处理,如更新页面显示、进行数据计算等。如果请求的是一张图片,响应体就是图片的二进制数据,客户端会将这些数据渲染成图片展示给用户。
以下是一个完整的响应报文示例:
HTTP/1.1 200 OK
Date: Mon, 15 Jul 2024 12:34:56 GMT
Server: Apache/2.4.54 (Unix)
Content - Type: text/html; charset=UTF - 8
Content - Length: 1024
Cache - Control: max - age = 3600
Set - Cookie: session_id=123abc; expires=Mon, 15 Jul 2024 13:34:56 GMT; path=/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF - 8">
<title>Example Page</title>
</head>
<body>
<h1>Welcome to the Example Page</h1>
<p>This is some sample content.</p>
</body>
</html>
在这个响应报文中,响应首行表明使用的HTTP版本为1.1
,状态码为200
,表示请求成功。响应头部分包含了服务器生成响应的时间、服务器软件类型、响应内容的类型和编码、响应体长度、缓存控制以及设置的Cookie
等信息。空行之后是响应体,包含了一个简单的HTML网页内容,客户端接收到这个响应报文后,会根据响应头的信息对响应体进行正确的解析和处理,最终在浏览器中展示出对应的网页。
3.3 常见的请求方法
在HTTP协议中,定义了多种请求方法,每种方法都有其特定的用途和语义。这些请求方法为客户端与服务器之间的交互提供了丰富的手段,使得开发者能够根据不同的业务需求,灵活地对服务器资源进行操作。以下是对常见请求方法的详细介绍:
3.3.1 GET
GET
方法是最常用的HTTP请求方法之一,主要用于从服务器获取指定的资源。它的特点是将请求参数直接附加在URL的查询字符串中,例如https://example.com/products?category=electronics&sort=price
,其中category=electronics
和sort=price
就是请求参数,分别表示要获取的产品类别为电子产品,并且按照价格进行排序。
由于GET
方法将参数暴露在URL中,所以在安全性要求较高的场景下,不适合传输敏感信息,如用户密码、银行卡号等。因为URL可能会被记录在浏览器历史记录、服务器日志中,或者在共享链接时被他人看到。不过,GET
方法在获取公开资源、进行简单查询等场景中非常方便。例如,在搜索引擎中输入关键词进行搜索,浏览器就是通过GET
方法将关键词作为参数发送给搜索引擎服务器,服务器根据这些参数返回相关的搜索结果。
在实际应用中,当我们访问一个网页时,浏览器会发送一系列的GET
请求,获取网页的HTML文件、CSS样式表、JavaScript脚本、图片等资源。例如,当访问https://example.com/index.html
时,浏览器首先会发送一个GET
请求获取index.html
文件,然后根据index.html
中引用的资源,如<link rel="stylesheet" href="styles.css">
和<script src="script.js"></script>
,再分别发送GET
请求获取styles.css
和script.js
文件。对于网页中的图片,如<img src="image.jpg">
,浏览器也会发送GET
请求来获取对应的图片资源。
3.3.2 POST
POST
方法主要用于向服务器提交数据,这些数据通常包含在请求体中。与GET
方法不同,POST
方法不会将数据暴露在URL中,因此更适合用于传输敏感信息,如用户注册信息、登录密码、表单数据等。例如,在用户注册页面填写用户名、密码、邮箱等信息后,点击提交按钮,浏览器会将这些信息以POST
方法发送给服务器,请求体可能如下:
username=john&password=123456&email=john@example.com
服务器接收到POST
请求后,会从请求体中提取数据,并进行相应的处理,如将用户注册信息保存到数据库中。
在Web应用中,POST
方法广泛应用于各种需要向服务器提交数据的场景。例如,在电商网站中,用户将商品添加到购物车、提交订单等操作,通常都是通过POST
方法实现的。在论坛或博客中,用户发表评论、发布文章也会使用POST
方法将评论内容或文章内容发送给服务器。
此外,POST
方法还常用于文件上传。当用户上传文件时,请求体的格式通常为multipart/form - data
,这种格式可以将文件内容和其他表单数据一起发送给服务器。例如,用户上传一张图片,同时填写了图片的描述信息,请求体可能包含图片的二进制数据以及描述信息的键值对,服务器接收到请求后,会将图片保存到指定的存储位置,并将描述信息与图片关联起来。
3.3.3 PUT
PUT
方法用于向服务器上传资源,它的主要作用是创建或更新服务器上的资源。例如,当我们需要在服务器上创建一个新的文件或者更新一个已有的文件内容时,可以使用PUT
方法。假设我们有一个名为example.txt
的文件,内容为Hello, World!
,现在要将其更新为Hello, HTTP!
,可以通过PUT
方法发送一个请求,请求体包含新的文件内容,如下所示:
PUT /example.txt HTTP/1.1
Host: example.com
Content - Type: text/plain
Content - Length: 13
Hello, HTTP!
服务器接收到这个请求后,会根据请求的资源路径/example.txt
找到对应的文件,如果文件不存在,服务器会创建一个新的文件;如果文件存在,服务器会用请求体中的内容覆盖原文件的内容。
在实际应用中,PUT
方法常用于对资源进行全量更新的场景。例如,在一个内容管理系统中,管理员可以使用PUT
方法将更新后的文章内容上传到服务器,以更新服务器上的文章资源。不过,需要注意的是,PUT
方法在使用时需要确保服务器端对请求的安全性和权限进行严格的验证,以防止未经授权的用户对资源进行恶意修改。
3.3.4 DELETE
DELETE
方法顾名思义,用于删除服务器上的指定资源。它通过请求的资源路径来确定要删除的资源。例如,要删除服务器上的/products/123
这个资源,可以发送如下的DELETE
请求:
DELETE /products/123 HTTP/1.1
Host: example.com
服务器接收到这个请求后,会根据资源路径/products/123
查找对应的资源,并将其从服务器上删除。
在实际应用中,DELETE
方法常用于删除数据库中的记录、文件系统中的文件等场景。例如,在一个电商系统中,当管理员要删除某个已下架的商品信息时,可以使用DELETE
方法向服务器发送请求,删除数据库中对应的商品记录。在文件管理系统中,用户可以使用DELETE
方法删除不再需要的文件。与PUT
方法类似,DELETE
方法在使用时也需要进行严格的权限控制,以防止用户误删或恶意删除重要资源。
3.3.5 HEAD
HEAD
方法与GET
方法类似,都是用于从服务器获取资源相关的信息。不同之处在于,HEAD
方法只请求资源的首部信息,而不会返回资源的主体内容。例如,当我们想获取一个文件的大小、修改时间、内容类型等信息,但不需要获取文件的实际内容时,可以使用HEAD
方法。发送一个HEAD
请求如下:
HEAD /example.txt HTTP/1.1
Host: example.com
服务器接收到这个请求后,会返回与该文件相关的首部信息,例如:
HTTP/1.1 200 OK
Date: Mon, 15 Jul 2024 14:00:00 GMT
Server: Apache/2.4.54 (Unix)
Content - Type: text/plain
Content - Length: 13
Last - Modified: Sun, 14 Jul 2024 10:00:00 GMT
通过这些首部信息,我们可以了解到文件的内容类型是纯文本,文件大小为13字节,最后修改时间是2024年7月14日10点。
在实际应用中,HEAD
方法有很多用途。例如,在进行文件下载前,可以先使用HEAD
方法获取文件的大小,以便在客户端显示下载进度条。在检查文件是否存在时,也可以使用HEAD
方法,如果服务器返回状态码为200
,说明文件存在;如果返回404
,则说明文件不存在。此外,HEAD
方法还可以用于缓存控制,通过检查资源的首部信息,如Last - Modified
和ETag
,可以判断资源是否发生了变化,从而决定是否需要从服务器重新下载资源。
3.3.6 OPTIONS
OPTIONS
方法用于获取服务器支持的HTTP方法和其他相关信息。通过发送OPTIONS
请求,客户端可以了解到服务器对于特定资源所支持的请求方法。例如,要查看服务器对于/products
这个资源支持哪些请求方法,可以发送如下的OPTIONS
请求:
OPTIONS /products HTTP/1.1
Host: example.com
服务器接收到这个请求后,会返回一个包含Allow
首部字段的响应,该字段列出了服务器支持的请求方法,例如:
HTTP/1.1 200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS
从这个响应中,客户端可以得知服务器对于/products
这个资源支持GET
、POST
、PUT
、DELETE
和OPTIONS
这几种请求方法。
在实际应用中,OPTIONS
方法常用于跨域资源共享(CORS)的预检请求。当一个网页从不同的域名加载资源时,浏览器会先发送一个OPTIONS
请求到服务器,检查服务器是否允许该跨域请求。服务器通过响应的首部信息告知浏览器是否允许跨域访问,以及允许的请求方法、请求头字段等信息。此外,OPTIONS
方法还可以用于测试服务器的配置和功能,帮助开发者了解服务器对于不同请求方法的支持情况。
3.3.7 PATCH
PATCH
方法用于对服务器上的资源进行部分更新。与PUT
方法不同,PUT
方法通常用于全量更新资源,即使用请求体中的内容完全覆盖服务器上的原有资源;而PATCH
方法则是对资源的部分内容进行修改。例如,假设服务器上有一个用户资源,包含用户名、邮箱和地址信息,现在只需要更新用户的地址信息,可以使用PATCH
方法发送如下请求:
PATCH /users/123 HTTP/1.1
Host: example.com
Content - Type: application/json
Content - Length: 34
{"address": "New Address 123"}
服务器接收到这个请求后,会根据资源路径/users/123
找到对应的用户资源,然后只更新其中的地址信息,而不会影响用户名和邮箱等其他信息。
在实际应用场景中,PATCH
方法非常适用于需要对复杂资源进行局部修改的情况。例如在一个项目管理系统中,项目的状态可能随时发生变化,如从"进行中"变为"已完成",此时使用PATCH
方法来更新项目的状态字段,就不会影响到项目的其他详细信息,如项目名称、负责人、开始时间等。又比如在电商系统中,商品的库存数量会随着销售情况实时更新,通过PATCH
方法只更新库存数量这一属性,能高效且精准地维护商品信息。
与其他请求方法配合使用时,PATCH
方法进一步丰富了对服务器资源的操作手段。例如在一个内容管理系统中,当用户创建新的文章时,使用POST
方法将完整的文章内容提交到服务器。后续若需要对文章的某个段落进行修改,就可以通过PATCH
方法,仅发送修改后的段落内容,减少不必要的数据传输。而当需要删除这篇文章时,则使用DELETE
方法。这样的组合使用,既满足了不同的业务需求,又提升了系统的性能和数据的完整性。
3.3.8 TRACE
TRACE
方法用于回显服务器收到的请求,主要用于测试和诊断目的。当客户端发送一个TRACE
请求时,服务器会将接收到的请求原样返回给客户端,包括请求的首部、请求体等信息。例如,客户端发送如下TRACE
请求:
TRACE / HTTP/1.1
Host: example.com
User - Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q = 0.9,image/avif,image/webp,image/apng,*/*;q = 0.8
服务器接收到这个请求后,会返回类似这样的响应:
HTTP/1.1 200 OK
Content - Type: message/http
Content - Length: 238
TRACE / HTTP/1.1
Host: example.com
User - Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q = 0.9,image/avif,image/webp,image/apng,*/*;q = 0.8
通过这种方式,客户端可以检查请求在传输过程中是否被正确处理,以及服务器是否正确接收到了请求的各个部分。在实际应用中,TRACE
方法可以帮助开发者排查网络故障,确定请求在传输过程中是否被篡改或丢失部分信息。例如,如果在开发过程中遇到请求无法正常被服务器处理的情况,通过发送TRACE
请求,可以查看服务器实际接收到的请求内容,对比发送的原始请求,找出可能存在的问题,如请求头字段是否被错误修改、请求体是否完整等。
3.3.9 CONNECT
CONNECT
方法主要用于建立隧道,通常用于代理服务器场景。它允许客户端与服务器之间建立一个双向的通信通道,通过这个通道,客户端可以间接访问其他服务器。例如,当客户端需要通过代理服务器访问一个HTTPS网站时,客户端会向代理服务器发送一个CONNECT
请求,请求的目标是要访问的HTTPS网站的地址和端口,如下所示:
CONNECT example.com:443 HTTP/1.1
Host: proxy.example.com
代理服务器接收到这个请求后,如果验证通过,会返回一个状态码为200
的响应,表示连接成功建立。此时,客户端和代理服务器之间就建立了一个隧道,客户端可以通过这个隧道向目标服务器发送请求,代理服务器会将请求转发到目标服务器,并将目标服务器的响应转发回客户端。在实际应用中,CONNECT
方法在企业网络中应用广泛,企业可以通过代理服务器使用CONNECT
方法来管理员工对外部网络的访问,如限制访问某些特定的网站、监控网络流量等。同时,在一些安全场景中,如使用VPN(虚拟专用网络)时,也会用到CONNECT
方法来建立安全的连接隧道,确保数据在不安全的网络环境中传输的安全性。
3.4 常见的响应状态码
在HTTP协议中,响应状态码是服务器向客户端传达请求处理结果的重要方式。每个状态码都有其特定的含义,通过对状态码的解读,客户端能够了解到请求是否成功、资源是否存在以及服务器是否出现错误等信息。以下是对常见响应状态码的详细分类和解释:
3.4.1 1xx(信息性状态码)
这类状态码表示服务器已经接收了客户端的请求,并且正在继续处理。它们通常用于提供一些中间信息,让客户端了解请求的处理进度。不过,在实际的Web应用中,1xx状态码并不常见,因为大多数客户端并不处理这类状态码。例如,100 Continue
状态码表示服务器已经收到请求的第一部分(通常是请求头),并且准备好接收请求体。当客户端发送一个包含较大请求体的请求时,可能会先发送请求头,服务器接收到请求头后,如果认为请求是有效的,会返回100 Continue
状态码,通知客户端可以继续发送请求体。这种情况在使用POST
或PUT
方法上传大文件时较为常见。
3.4.2 2xx(成功状态码)
这是一组表示请求成功处理的状态码,是客户端最希望看到的响应结果。
- 200 OK :这是最常见的成功状态码,表示服务器成功处理了客户端的请求,并将请求的资源正常返回给客户端。例如,当用户在浏览器中访问一个网页时,如果服务器返回
200 OK
状态码,说明服务器找到了对应的网页文件,并将其内容发送给了浏览器,浏览器可以正常渲染该网页。无论是简单的HTML页面请求,还是复杂的API请求,只要请求处理成功,服务器通常都会返回200 OK
状态码。 - 201 Created :当客户端使用
POST
、PUT
等方法创建新资源时,如果服务器成功创建了资源,就会返回201 Created
状态码。同时,服务器会在响应头中通过Location
字段指定新创建资源的URL地址。例如,在用户注册一个新账号后,服务器会返回201 Created
状态码,并在Location
字段中给出该用户账号的详细信息页面的URL,客户端可以通过这个URL进一步获取或操作新创建的资源。 - 204 No Content :表示服务器成功处理了请求,但没有返回任何内容。这种情况通常出现在客户端执行了某些不需要返回具体数据的操作时,如使用
DELETE
方法删除资源后,服务器可能会返回204 No Content
状态码,告知客户端资源已成功删除,但不需要返回额外的信息。
3.4.3 3xx(重定向状态码)
这类状态码表示客户端需要采取进一步的操作来完成请求。通常是由于资源的位置发生了变化,服务器通过重定向状态码引导客户端到新的位置获取资源。
- 301 Moved Permanently :表示请求的资源已经被永久移动到新的URL地址。服务器会在响应头中通过
Location
字段指定新的URL。例如,当一个网站进行改版,某个页面的URL发生了永久性变化时,服务器会对该页面的旧URL请求返回301 Moved Permanently
状态码,并在Location
字段中给出新的URL。搜索引擎在遇到301
重定向时,会更新其索引,将旧URL指向的页面内容更新为新URL对应的内容。 - 302 Found :也称为临时重定向,与
301
类似,但表示资源只是暂时移动到新的URL地址。客户端在收到302 Found
状态码后,应该继续使用原来的URL进行后续请求,除非服务器明确指示需要使用新的URL。例如,在进行用户登录验证时,如果用户未登录而访问了需要登录权限的页面,服务器可能会返回302 Found
状态码,并将Location
字段设置为登录页面的URL,引导用户进行登录操作。 - 304 Not Modified :这个状态码用于缓存控制。当客户端发送一个带有缓存相关信息(如
If - Modified - Since
或If - None - Match
等请求头)的请求时,如果服务器判断资源没有发生变化,就会返回304 Not Modified
状态码。客户端接收到这个状态码后,会从本地缓存中获取资源,而不需要再次从服务器下载,从而节省了带宽和网络请求时间。例如,用户在短时间内多次访问同一个网页,浏览器会在请求中带上之前获取该网页时的缓存信息,服务器检查后发现网页内容没有变化,就会返回304 Not Modified
状态码,浏览器则直接从本地缓存中读取网页内容进行显示。
3.4.4 4xx(客户端错误状态码)
这组状态码表示客户端发送的请求存在错误,服务器无法处理该请求。
- 400 Bad Request :表示客户端发送的请求存在语法错误或其他问题,服务器无法理解该请求。例如,客户端在发送一个
POST
请求时,请求体的格式不符合服务器的要求,服务器就会返回400 Bad Request
状态码。这种情况可能是由于客户端代码编写错误、数据格式转换错误等原因导致的。 - 401 Unauthorized :表示客户端需要进行身份验证才能访问请求的资源,但客户端没有提供有效的身份凭证,或者提供的凭证无效。例如,在访问一个需要登录的API接口时,如果客户端没有在请求头中携带有效的令牌(Token),服务器会返回
401 Unauthorized
状态码。此时,客户端需要获取有效的身份凭证(如通过登录获取令牌),然后重新发送请求。 - 403 Forbidden :表示服务器理解客户端的请求,但拒绝执行该请求,通常是因为客户端没有足够的权限访问请求的资源。例如,普通用户尝试访问管理员专用的页面或API接口,服务器会返回
403 Forbidden
状态码。与401 Unauthorized
不同,403 Forbidden
是在客户端已经通过身份验证的情况下,由于权限不足导致的访问被拒。 - 404 Not Found :这是一个非常常见的状态码,表示服务器无法找到客户端请求的资源。例如,用户在浏览器中输入了一个错误的URL地址,或者服务器上对应的资源已经被删除,服务器就会返回
404 Not Found
状态码。在Web应用开发中,需要合理处理404
状态码,为用户提供友好的提示信息,如显示一个"页面未找到"的页面。 - 405 Method Not Allowed :当客户端使用的请求方法不被服务器允许时,服务器会返回
405 Method Not Allowed
状态码。例如,服务器只允许对某个资源使用GET
方法获取数据,但客户端使用了POST
方法,服务器就会返回这个状态码。同时,服务器会在响应头中通过Allow
字段列出该资源允许使用的请求方法,如Allow: GET, HEAD
,客户端可以根据这个信息调整请求方法。
3.4.5 5xx(服务器错误状态码)
这类状态码表示服务器在处理客户端请求时发生了错误,无法完成请求的处理。
- 500 Internal Server Error :这是最常见的服务器错误状态码,表示服务器内部发生了未预期的错误,导致无法完成请求的处理。例如,服务器端的代码出现了空指针异常、数据库连接失败等问题,都可能导致服务器返回
500 Internal Server Error
状态码。在这种情况下,服务器通常会记录详细的错误日志,开发人员可以通过查看日志来排查问题。 - 503 Service Unavailable :表示服务器暂时无法处理客户端的请求,通常是由于服务器过载、维护或者某些服务不可用导致的。例如,服务器正在进行系统升级、资源池耗尽等情况,都可能返回
503 Service Unavailable
状态码。此时,客户端可以尝试在一段时间后重新发送请求。服务器在返回503
状态码时,通常会在响应头中通过Retry - After
字段指定客户端应该等待的时间,例如Retry - After: 60
表示客户端应该在60秒后再次尝试请求。 - 504 Gateway Timeout :当服务器作为网关或代理服务器时,如果在规定的时间内没有从上游服务器(如后端的应用服务器、数据库服务器等)收到响应,就会返回
504 Gateway Timeout
状态码。例如,在一个多层架构的Web应用中,前端服务器作为网关向后端应用服务器转发请求,如果后端应用服务器由于某种原因响应缓慢,超过了前端服务器设置的超时时间,前端服务器就会返回504 Gateway Timeout
状态码给客户端。客户端可以根据这个状态码判断是网络传输过程中出现了问题,或者后端服务器存在性能瓶颈。
3.5 常见的请求头和响应头
在HTTP通信中,请求头和响应头承载了大量关于请求和响应的元信息,它们对于客户端和服务器之间的正确交互至关重要。通过这些头信息,双方可以了解彼此的能力、偏好、资源状态等,从而更高效地进行数据传输和处理。
3.5.1 常见的请求头
- User - Agent :这个请求头用于标识客户端的信息,包括使用的操作系统、浏览器类型及版本等。例如,
User - Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
,从这个User - Agent
字符串中,服务器可以得知客户端使用的是Windows 10操作系统,64位版本,浏览器是Chrome,版本号为114.0.0.0,并且基于WebKit内核。服务器可以根据这些信息对不同的客户端进行适配,比如为不同浏览器提供不同版本的CSS样式或JavaScript代码,以确保网页在各种浏览器上都能正确显示和运行。 - Accept :用于告知服务器客户端能够接受的响应内容类型。例如,
Accept: text/html,application/xhtml+xml,application/xml;q = 0.9,image/avif,image/webp,image/apng,*/*;q = 0.8
,这表示客户端优先接受HTML格式的内容,其次是XHTML、XML格式,q
值表示相对优先级,q = 1
为最高优先级,q = 0
表示不接受。对于图片格式,客户端支持avif
、webp
、apng
等,并且对于其他未明确列出的内容类型,也可以接受,但优先级较低。服务器根据这个请求头,选择合适的内容类型返回给客户端。 - Accept - Encoding :指定客户端支持的编码格式,常见的有
gzip
、deflate
、br
等。例如,Accept - Encoding: gzip, deflate
,这意味着客户端可以接受服务器使用gzip
或deflate
算法对响应内容进行压缩。服务器如果支持这些编码格式,会对响应内容进行压缩后再发送,这样可以减少数据传输量,提高传输速度。客户端接收到压缩后的内容后,会根据请求头中指定的编码格式进行解压缩。 - Accept - Language :表示客户端偏好的语言。例如,
Accept - Language: en - US,en;q = 0.9,zh - CN;q = 0.8
,这表明客户端首选美式英语,其次是英式英语,最后是简体中文。服务器可以根据这个请求头,返回对应语言的内容,如在多语言网站中,根据用户的语言偏好显示不同语言版本的网页。 - Cookie :用于在客户端和服务器之间传递会话信息。当客户端首次访问服务器时,服务器可以通过设置
Set - Cookie
响应头在客户端设置Cookie
。后续客户端再次向服务器发送请求时,会在请求头中包含Cookie
信息,服务器可以根据这些Cookie
识别用户身份、跟踪用户会话等。例如,Cookie: session_id=1234567890abcdef; username=john
,服务器可以通过session_id
识别用户的会话状态,通过username
获取用户的相关信息。 - Referer :这个请求头记录了当前请求的来源页面的URL。例如,用户在网页A上点击一个链接跳转到网页B,那么网页B的服务器在接收到请求时,请求头中的
Referer
字段会包含网页A的URL。服务器可以利用这个信息进行统计分析,了解用户是从哪些页面进入到当前页面的,也可以用于防止盗链,即禁止其他网站未经授权地引用本网站的资源。例如,如果一个图片服务器发现某个请求的Referer
不是本网站的页面,而是其他网站的页面,可能会拒绝提供图片资源,以保护网站的资源和带宽。 - Content - Type :当请求体存在时,这个请求头用于指定请求体的内容类型。例如,在使用
POST
方法提交表单数据时,如果表单数据是按照application/x - www - form - urlencoded
格式编码的,那么请求头中会包含Content - Type: application/x - www - form - urlencoded
。如果是上传JSON格式的数据,请求头可能是Content - Type: application/json
。服务器根据这个请求头,正确解析请求体中的数据。 - Content - Length :用于指定请求体的长度。例如,当客户端发送一个包含大量数据的
POST
请求时,请求头中的``Content - Length字段会告知服务器请求体的字节数。服务器根据这个长度信息,准确地读取请求体中的全部数据。例如,
Content - Length: 1024`表示请求体的大小为1024字节。这有助于服务器在接收数据时,判断是否完整接收了所有数据,避免因数据截断导致的错误处理。
3.5.2 常见的响应头
- Content - Type :用于指定响应体的内容类型,让客户端知道如何处理接收到的数据。例如,
Content - Type: text/html; charset=UTF - 8
表明响应体是HTML格式的文档,并且字符编码为UTF - 8。客户端的浏览器会根据这个信息,正确地解析和渲染HTML内容。如果是Content - Type: application/json
,客户端则会将响应体解析为JSON格式的数据,以便进一步处理,如在JavaScript中使用JSON.parse()
方法将其转换为对象。 - Content - Length :告知客户端响应体的长度,以字节为单位。客户端可以根据这个信息,在接收数据时判断是否已完整接收所有响应内容。例如,
Content - Length: 2048
表示响应体的大小为2048字节。这对于处理大文件下载或分块接收数据时非常重要,确保客户端能够准确地获取全部数据。 - Set - Cookie :服务器使用这个响应头在客户端设置
Cookie
。例如,Set - Cookie: session_id=abcdef; expires=Thu, 31 Dec 2025 23:59:59 UTC; path=/
,该指令会在客户端设置一个名为session_id
的Cookie
,其值为abcdef
,过期时间为2025年12月31日23点59分59秒,且在整个网站根目录(path=/
)下都有效。后续客户端在访问该网站的其他页面时,会自动在请求头中带上这个Cookie
,服务器可以通过读取Cookie
来识别用户身份、跟踪用户会话等。 - Cache - Control :用于控制缓存行为,决定客户端和中间缓存(如代理服务器)如何处理响应内容的缓存。例如,
Cache - Control: no - cache
表示不允许客户端缓存响应内容,每次请求都需要从服务器重新获取,以确保客户端获取到的是最新数据。Cache - Control: max - age = 3600
则表示响应内容可以被缓存,且在接下来的3600秒(1小时)内,客户端可以直接从缓存中读取数据,而无需再次向服务器发送请求,这有助于减少网络请求次数,提高页面加载速度。 - Expires :指定响应内容的过期时间。例如,
Expires: Thu, 31 Dec 2025 23:59:59 UTC
表示在这个时间点之后,该响应内容被认为是过期的,客户端应从服务器重新获取。与Cache - Control
中的max - age
类似,都是用于控制缓存,但Expires
使用的是绝对时间,而max - age
使用的是相对时间。在实际应用中,Cache - Control
更为常用,因为它更灵活,且不受客户端和服务器时间不一致的影响。 - Location :当服务器返回重定向状态码(如
301 Moved Permanently
、302 Found
)时,这个响应头指定客户端应重定向到的URL地址。例如,Location: https://new - domain.com/new - page.html
,客户端接收到包含此Location
头的响应后,会自动向指定的URL发送新的请求。这在网站改版、资源迁移或用户登录跳转等场景中经常使用。 - Server :用于标识服务器使用的软件名称和版本。例如,
Server: Apache/2.4.54 (Unix)
表示服务器使用的是Apache软件,版本号为2.4.54,运行在Unix操作系统上。虽然这个信息对于普通用户来说可能没有直接意义,但对于网站管理员和安全人员来说,它可以帮助了解服务器的技术架构,以便进行相应的维护和安全防范。例如,当发现某个版本的服务器软件存在安全漏洞时,管理员可以及时进行升级或采取其他安全措施。 - ETag :即实体标签(Entity Tag),是服务器为资源生成的唯一标识。它用于缓存验证,当客户端再次请求资源时,会在请求头中包含之前获取的
ETag
值(通过If - None - Match
请求头),服务器通过比较客户端提供的ETag
与当前资源的ETag
是否一致,来判断资源是否发生了变化。如果一致,服务器可以返回304 Not Modified
状态码,客户端则从本地缓存中获取资源,避免了重复下载。例如,服务器为某个图片资源生成的ETag
为"abc123"
,当客户端下次请求该图片时,会在请求头中发送If - None - Match: "abc123"
,服务器对比后若发现图片未修改,就返回304 Not Modified
。 - Last - Modified :指定资源的最后修改时间。客户端在后续请求中,可以通过
If - Modified - Since
请求头带上之前获取的Last - Modified
时间,服务器根据这个时间判断资源是否发生了变化。如果资源没有更新,服务器同样可以返回304 Not Modified
状态码,让客户端使用本地缓存。例如,Last - Modified: Mon, 15 Jul 2024 10:00:00 GMT
,当客户端再次请求该资源时,会在请求头中发送If - Modified - Since: Mon, 15 Jul 2024 10:00:00 GMT
,服务器通过比较当前资源的修改时间与客户端提供的时间,决定是否返回最新资源。
3.6 HTTP与HTTPS的区别
在当今的网络环境中,HTTP和HTTPS是两种常见的网络协议,它们在数据传输的安全性和性能等方面存在显著差异。理解这些区别对于保障网络通信的安全和高效至关重要。
3.6.1 安全性
- HTTP:是一种明文传输协议,这意味着在数据传输过程中,内容不会经过加密处理。例如,当用户在使用HTTP协议的网站上输入用户名和密码进行登录时,这些信息会以明文形式在网络中传输。如果网络中存在恶意攻击者,他们可以通过抓包工具轻松获取这些信息,从而导致用户信息泄露,引发安全风险,如账号被盗用、个人隐私泄露等问题。
- HTTPS:是在HTTP的基础上,通过添加SSL/TLS(安全套接层/传输层安全)协议来实现数据加密传输。在HTTPS通信过程中,客户端和服务器之间会进行握手,协商加密算法和密钥。然后,所有传输的数据都会使用这些密钥进行加密,变成密文在网络中传输。即使攻击者截取到这些数据,由于没有解密密钥,也无法获取其中的真实内容。例如,在使用HTTPS协议的在线支付页面,用户输入的银行卡信息、支付金额等敏感数据在传输过程中都是加密的,有效保障了用户的资金安全和隐私。
3.6.2 证书
- HTTP:不需要使用数字证书来验证服务器身份。这使得攻击者有可能伪装成合法的服务器,向用户提供虚假的网页内容,实施钓鱼攻击。例如,攻击者可以创建一个与银行官方网站极为相似的虚假网站,诱使用户输入账号密码等信息,从而骗取用户的钱财。
- HTTPS:服务器需要向CA(证书颁发机构)申请数字证书。CA会对服务器的身份进行严格审核,只有通过审核的服务器才能获得证书。当客户端与服务器建立连接时,服务器会将数字证书发送给客户端。客户端会验证证书的合法性,包括证书是否由受信任的CA颁发、证书是否过期、证书中的域名是否与访问的域名一致等。如果证书验证通过,客户端才会与服务器进行安全通信。例如,当用户访问大型电商网站的HTTPS页面时,浏览器会自动验证网站的数字证书,只有证书合法有效,浏览器才会显示安全锁标志,让用户放心进行购物等操作。
3.6.3 性能
- HTTP:由于不需要进行加密和解密操作,其通信过程相对简单,因此在性能方面相对较高。在一些对安全性要求不高,但对速度要求较高的场景,如一些公开的新闻资讯网站,使用HTTP协议可以更快地加载页面,提高用户体验。
- HTTPS:加密和解密操作会消耗一定的系统资源和时间,从而增加了通信的延迟。此外,SSL/TLS握手过程也会带来额外的开销,使得首次连接的时间相对较长。不过,随着硬件性能的提升和加密算法的优化,这种性能差异在现代网络环境中已经逐渐减小。而且,对于涉及用户敏感信息的场景,如网上银行、在线购物等,HTTPS提供的安全性远远超过了其在性能上的微小损耗。
3.6.4 端口
- HTTP :默认使用端口号80。当客户端发起一个HTTP请求时,通常会通过80端口与服务器进行通信。例如,在浏览器中输入
http://example.com
,浏览器会自动尝试通过80端口连接到example.com
服务器。 - HTTPS :默认使用端口号443。当客户端发起一个HTTPS请求时,会通过443端口与服务器建立安全连接。例如,在浏览器中输入
https://example.com
,浏览器会通过443端口与服务器进行SSL/TLS握手,并在握手成功后进行加密通信。
3.6.5 URL前缀
- HTTP :其URL前缀为
http://
。例如,常见的新闻网站http://news.example.com
,用户在访问此类网站时,地址栏中显示的就是以http://
开头的URL。 - HTTPS :其URL前缀为
https://
。例如,电商购物网站https://shop.example.com
,当用户访问该网站时,浏览器地址栏会显示以https://
开头的URL,并且通常会在地址栏附近显示安全锁标志,提示用户当前连接是安全的。
3.7 总结
HTTP协议作为Web应用的基础,其请求和响应报文的格式、各种请求方法、状态码以及头信息等构成了客户端与服务器之间交互的规范。不同的请求方法适用于不同的业务场景,如GET
用于获取资源,POST
用于提交数据等。状态码则清晰地传达了请求处理的结果,帮助客户端做出相应的决策。请求头和响应头承载了丰富的元信息,为双方提供了关于对方的能力、偏好以及资源状态等信息。
随着网络安全需求的增长,HTTPS在HTTP的基础上通过SSL/TLS协议实现了数据加密传输,并引入数字证书验证服务器身份,大大提高了网络通信的安全性。尽管在性能上略有损耗,但在涉及敏感信息传输的场景中,其安全性优势无可替代。
在实际的Web开发和网络应用中,深入理解HTTP和HTTPS的原理、特性以及它们之间的区别,对于开发安全、高效的Web应用至关重要。开发者需要根据应用的具体需求,合理选择使用HTTP或HTTPS协议,并正确处理各种请求和响应,以提供良好的用户体验和数据安全保障。同时,随着技术的不断发展,HTTP协议也在持续演进,如HTTP/2和HTTP/3的出现,为Web性能带来了进一步的提升,开发者也需要关注这些新技术的发展,不断优化自己的应用。
3.8 实战案例分析
3.8.1 电商网站的登录功能
在电商网站中,用户登录功能是极为关键的环节,涉及到大量用户敏感信息的传输,因此HTTPS协议的应用必不可少。
当用户在登录页面输入用户名和密码后,浏览器会构建一个HTTP请求。该请求首行通常为POST /login HTTP/1.1
,表明使用POST
方法向服务器的/login
路径发送请求。请求头部分会包含User - Agent
字段,用于告知服务器用户使用的设备和浏览器信息,例如User - Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1
。同时,Content - Type
字段会指定为application/x - www - form - urlencoded
,因为登录表单数据通常以此格式进行编码。而Content - Length
字段则会明确请求体的长度。
请求体中会包含用户输入的用户名和密码等信息,如username=JohnDoe&password=secret123
。由于该过程涉及用户敏感信息,电商网站会采用HTTPS协议进行通信。服务器接收到请求后,会验证用户输入的用户名和密码是否正确。如果验证成功,服务器会返回一个响应。
响应首行为HTTP/1.1 200 OK
,表示请求成功处理。响应头中Content - Type
字段可能为application/json
,因为服务器可能以JSON格式返回用户的相关信息,如用户ID、用户名、用户等级等。Set - Cookie
字段会被设置,用于在客户端保存用户的会话信息,例如Set - Cookie: session_id=abcdef123456; expires=Thu, 31 Dec 2025 23:59:59 UTC; path=/
。这样,用户在后续浏览网站其他页面时,无需再次登录,浏览器会自动在请求头中携带Cookie
信息,服务器通过验证Cookie
来识别用户身份。
3.8.2 图片资源的获取与缓存
在一个图片分享网站中,HTTP协议的请求方法和缓存机制在图片资源的获取过程中发挥着重要作用。
当用户打开图片分享网站的页面时,浏览器会向服务器发送一系列的GET
请求来获取页面上的图片资源。例如,对于一张图片的请求,请求首行为GET /images/picture1.jpg HTTP/1.1
,请求头中的User - Agent
字段同样会标识浏览器和设备信息。Accept
字段会表明客户端能够接受的图片格式,如Accept: image/avif,image/webp,image/jpeg,image/png,image/gif
。
服务器接收到请求后,会返回包含图片的响应。响应首行为HTTP/1.1 200 OK
,响应头中的Content - Type
字段会指定为image/jpeg
,表明响应体是JPEG格式的图片。Content - Length
字段则明确图片的大小,便于客户端准确接收。
为了提高性能和减少网络流量,服务器会利用缓存机制。服务器可能会在响应头中设置Cache - Control
字段,如Cache - Control: max - age = 3600
,表示该图片在客户端缓存中可以保持有效1小时。同时,服务器还会设置ETag
字段,为图片生成一个唯一标识,例如ETag: "abc123xyz"
。
当用户在1小时内再次访问该图片时,浏览器会在请求头中带上If - None - Match
字段,并包含之前获取的ETag
值,即If - None - Match: "abc123xyz"
。服务器接收到请求后,会对比当前图片的ETag
与客户端发送的ETag
。如果图片未发生变化,服务器会返回HTTP/1.1 304 Not Modified
响应,告知客户端直接从本地缓存中获取图片,从而避免了重复下载,节省了网络带宽和加载时间。
3.8.3 动态网页内容的更新与传输
在一个社交平台中,动态网页内容的实时更新和传输依赖于HTTP协议的高效处理。
当用户发布一条新的动态时,浏览器会向服务器发送一个POST
请求。请求首行为POST /post - dynamic HTTP/1.1
,请求头中的Content - Type
字段可能为application/json
,因为动态内容可能以JSON格式进行传输,例如{"user_id": 123, "content": "This is a new dynamic", "timestamp": "2024 - 07 - 15T12:34:56Z"}
。Content - Length
字段会指定请求体的长度。
服务器接收到请求后,将新的动态内容存储到数据库中,并返回一个响应。响应首行为HTTP/1.1 201 Created
,表示新的动态已成功创建。响应头中的Location
字段可能会指定新动态的详细页面URL,如Location: /dynamic/12345
,方便用户在发布后直接跳转到该动态的页面。
当其他用户浏览社交平台页面时,浏览器会定期向服务器发送GET
请求以获取最新的动态内容。例如,请求首行为GET /get - dynamics HTTP/1.1
。服务器会根据请求查询数据库,并将最新的动态内容以合适的格式返回。响应头中的Content - Type
字段可能为application/json
,响应体则包含一系列动态信息的JSON数组,如[{"user_id": 123, "content": "This is a new dynamic", "timestamp": "2024 - 07 - 15T12:34:56Z"}, {"user_id": 456, "content": "Another dynamic", "timestamp": "2024 - 07 - 15T13:00:00Z"}]
。
通过这种方式,社交平台能够实现动态网页内容的及时更新和高效传输,为用户提供实时的社交体验。
3.9 HTTP协议的未来展望
随着互联网技术的飞速发展,HTTP协议作为网络通信的基石,也在不断演进以适应新的需求和挑战。
3.9.1 性能优化的持续推进
HTTP/3的出现标志着在性能优化方面迈出了重要一步。基于QUIC协议,HTTP/3在减少连接建立延迟、提高网络拥塞控制能力等方面表现出色。未来,我们可以期待HTTP协议在性能优化上继续深入。例如,进一步优化多路复用技术,使得在同一连接上能够更高效地传输多个请求和响应,减少资源竞争和延迟。同时,对二进制传输格式的优化也将持续进行,以降低传输开销,提高数据传输的速度和准确性。
3.9.2 安全性的强化
在网络安全日益重要的今天,HTTP协议的安全性将不断得到强化。一方面,SSL/TLS协议也在持续更新,未来的HTTP版本将紧密结合最新的SSL/TLS特性,提供更强大的加密算法和更安全的密钥交换机制。另一方面,对于服务器和客户端的身份验证机制也将进一步完善,防止中间人攻击和身份伪造等安全威胁。例如,可能会引入更复杂的数字证书验证流程,或者结合生物识别技术等多因素认证方式,确保通信双方的身份安全。
3.9.3 对新兴技术的支持
随着物联网(IoT)、虚拟现实(VR)、增强现实(AR)等新兴技术的兴起,HTTP协议需要更好地支持这些领域的应用。在物联网环境中,大量的设备需要进行高效、安全的通信。HTTP协议未来可能会针对物联网设备的低功耗、低带宽特点进行优化,提供更轻量化的通信方式。对于VR和AR应用,由于需要实时传输大量的多媒体数据,HTTP协议需要在保证数据传输速度的同时,确保数据的完整性和准确性,以提供流畅的用户体验。
3.9.4 与其他协议的融合
未来HTTP协议可能会与其他网络协议进行更深度的融合。例如,与WebSocket协议的结合,WebSocket提供了全双工通信通道,能够实现实时的双向数据传输。HTTP协议与WebSocket的融合可以在Web应用中更好地支持实时交互功能,如实时聊天、在线游戏等。此外,与新兴的网络传输协议的融合也可能出现,以适应不断变化的网络环境和应用需求。
总之,HTTP协议在未来将继续扮演重要角色,通过不断的演进和创新,为互联网的发展提供坚实的支撑,推动各种网络应用的发展和普及,为用户带来更高效、更安全、更丰富的网络体验。