目录
- 前言
- WWW(万维网缩写)
- 超文本
- URL
- HTTP(1.0)
- 工作模式
- HTTP协议特点
- HTTP的请求和应答
- HTTP1.1
- 更加多的请求头和响应头
- 持续连接(PersistentConnection)
- 请求的流水线(Pipelining)
- 状态码100(Continue)
- 断点续传
- HTTP2.0
- 多路复用
- 数据压缩
- HTTP状态码(主要的)
- 首部字段(HTTP/1.1)
- Cookie
- Session
- 参考资料
前言
参照清华大学出版社-罗军周主编的《TCP/IP协议及网络编程技术》进行学习。
本篇主要参考第十二章:《HTTP协议》
主要将会介绍构成《WWW(World Wide Web
)》基础的《HTTP协议》。包括HTTP1.0/1.1/2.0.
WWW(万维网缩写)
WWW是环球信息网的缩写,(亦作“Web”、“WWW”、“'W3'”,英文全称为“World Wide Web”)
中文名字为“万维网”,"环球网"等,常简称为Web。万维网并不等同互联网
万维网只是互联网所能提供的服务其中之一,是靠着互联网运行的一项服务。
超文本
- 超文本除了基础的文本信息、还涵盖了诸如图片、视频、音频等其他资源。
其实已经发展为超媒体、但习惯上还是叫超文本。 - 超一个超文本由多个信息源链接而成、该文档除了基本的信息之外、还可以有指向信息集合中其他文本的指针(跳转)。
- 超文本的主要格式为HTML。
http——超文本传输协议资源
https——用安全套接字层传送的超文本传输协议
ftp——文件传输协议
mailto——电子邮件地址
ldap——轻型目录访问协议搜索
file——当地电脑或网上分享的文件
news——Usenet新闻组
gopher——Gopher协议
telnet——Telnet协议
URL
以下的介绍是针对以前的静态地址URL。
现在已经不适用了、现在的URL基本都会在后台服务器进行一些路由处理或者其他操作(比如从数据库查询数据、赋值到HTML模板里、然后再将html返回)。并不直接指向相应文件。
- 由于WWW是分布式的、同时指针指向的文档类型多样、这给如何描述这个指针带来了一定的困难(视频、音频、文字、不同的软件等等)。
- 为了组织描述远程项的各种信息、URL应运而生。
- URL把信息编码成一个字符串、称为统一资源定位(Uniform Resource Locator,URL)。
URL被冒号和斜杠分隔成三个部分:协议、计算机名、文档名。
protocol://computer_name:port/document_name
protocol:
访问文档所采用的协议名computer_name
文档所在的计算机域名port
协议端口号(可选)document_name
指定计算机上的文件名、包括路径和文件名
例如:
http://www.seu.edu.cn/cs/index.html
协议为http、计算机名为www.seu.edu.cn、文件cs/index.html
HTTP(1.0)
超文本传输协议是WEB服务器用来处理服务器和客户端之间数据流的协议。
基于TCP协议、作用于应用层。
-
工作模式
基于《请求/响应》模式进行工作。
为此HTTP协议定义了两种消息:来自客户端的《请求消息》与来自服务器的《应答消息》。
客户端在接收到用户指令后、将
打开
与服务器相连的TCP连接
的80端口(默认是80端口、也可以更改)、然后在此连接上发送相应的请求命令
。服务器在接收到请求命令后、对其作出相应的处理后、将其处理的结果以
应答消息
返回到客户端、并关闭
此次TCP连接
。-
HTTP协议特点
1. 支持客户/服务器模式
2. 简单快速
客户向服务器请求服务时、只需要传送请求方法和路径。请求方法常用GET
、HEAD
、POST
。每种方法规定了客户与服务器联系类型
的不同。由于HTTP协议简单、使得HTTP服务器的程序规模小、通信速度快。
3.灵活
HTTP允许传输任意类型的对象。正在传输的类型由Content-Type
加以标记。
4.无连接
HTTP协议每次只能处理一个请求。服务器处理完客户需求并且客户收到应答之后、即断开连接。
5.无状态
HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。它并不会记录同一个客户端之前所做了什么动作。
HTTP的请求和应答
-
HTTP请求的格式
其中第一行是请求行。<method>
是请求方法、URI
是请求资源的统一资源标识、<HTTP-version>
是协议版本号。
余下的分别是报文头(请求头)、报文体(请求体)。
举个实际的例子:
-
HTTP1.0中支持一下三种方式的请求
1. GET请求
负责资源的读取
2. HEAD请求
类似GET请求、但服务器只返回对应资源的首部信息
。
通常用来测试所请求资源的正确性、可访问性和最近的修改。GET和HEAD请求不会携带报文体
。
3. POST请求
用来负责数据的发送。应用于电子邮件、表格等等。
需要提供报文体
以及报文长度
。
-
应答消息
与请求消息类似、分为
消息头
和主体
两部分、中间以一行空白隔开。第一部分是
应答头
:以
状态行
开头(http版本、状态编码、原因短语)、跟随表达应答细节着首部字段
。如果有与应答有关的数据体、放在
body
(应答体
)部分。
HTTP1.1
这里会整理一下HTTP1.1与HTTP1.0的主要区别
- 更加多的请求头和响应头
- HTTP1.0没有host的字段
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。 - 身份认证、状态管理和Cache缓存等机制相关的请求头和响应头
- 持续连接(PersistentConnection)
- HTTP 1.1则支持持久连接Persistent Connection, 并且默认使用persistent connection.
- HTTP 1.1的持续连接,也需要增加新的请求头来帮助实现,例如,Connection请求头的值为Keep-Alive时,客户端通知服务器返回本次请求结果后保持连接;Connection请求头的值为close时,客户端通知服务器返回本次请求结果后关闭连接。
3.keep-alive timeout时间
keep-alive并不是免费的午餐,长时间的TCP连接容易导致系统资源无效占用,配置不当的keep-alive 有时比重复利用连接带来的损失还更大;因此,正确地设置keep-alive timeout时间非常重要。
在没有设置keepalive_timeout的情况下,一个socket资源从建立到真正释放所需要经过的时间是:建立TCP连接(三次握手)+传送http请求+脚本指向+传送http响应+关闭TCP连接(四次挥手)+主动关闭的一方进入TIME_WAIT的2MSL等待时间;
当设定了keepalive_timeout时间之后,一个socket由建立到释放所需要经过的时间是:TCP建立连接(三次握手)+(最后一次响应 - 第一次请求时间)+TCP关闭连接(四次挥手)+2MSL;
也就是说,当使用keep-alive机制的时候,当一次请求-响应结束之后,这个连接还会继续维持上keepalive_timeout时间,如果在这 个时间内client端还有请求发过来,那么server端会继续处理给予响应,如果keepalive_timeout时间计时结束后,就会进入TCP 释放连接的阶段,因此也就会结束掉这次通信;
- 请求的流水线(Pipelining)
- 在同一个tcp的连接中可以传送多个HTTP请求和响应. 多个请求和响应可以重叠,多个请求和响应可以同时进行。
- 例如:一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接。
- HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容。这也叫做队首阻塞。
状态码100(Continue)
HTTP/1.1加入了一个新的状态码100(Continue)。客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。100 (Continue) 状态代码的使用,允许客户端在发request消息body之前先用request header试探一下server,看server要不要接收request body,再决定要不要发request body。断点续传
HTTP/1.0每次传送文件都是从文件头开始,即0字节处开始。RANGE:bytes=XXXX表示要求服务器从文件XXXX字节处开始传送,断点续传。
HTTP2.0
- 多路复用
在HTTP1.1中虽然允许并行发送请求、但服务器的响应不允许多个错发送(多路复用),只能等待一个响应完全返回后,下一个响应才能发送,无论下一个响应是否早于前一个响应完成处理,这也叫做队首阻塞。
- HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。
- 当然HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。
- TCP连接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。因此对应瞬时并发的连接,服务器的响应就会变慢。所以最好能使用一个建立好的连接,并且这个连接可以支持瞬时并发的请求。
4. 多路复用的原理
基于二进制分帧层,HTTP 2.0可以在共享TCP连接的基础上,同时发送请求和响应。HTTP消息被分解为独立的帧,而不破坏消息本身的语义,交错发送出去,最后在另一端根据流ID和首部将它们重新组合起来
。
对于多路复用、这里不详解解释太多细节。有兴趣可以查阅《HTTP 2.0 原理详细分析》
-
数据压缩
HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
HTTP状态码(主要的)
-
2xx (请求成功)
200 | 成功 | 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页 |
---|---|---|
201 | 已创建 | 请求成功并且服务器创建了新的资源 |
202 | 已接受 | 服务器已接受请求,但尚未处理 |
-
3xx (重定向)
300 | 多种选择 | 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择 |
---|---|---|
301 | 永久移动 | 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置 |
302 | 临时移动 | 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求 |
303 | 查看其他位置 | 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码 |
304 | 未修改 | 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容 |
-
4xx(客户机错误)
400 | 错误请求 | 服务器不理解请求的语法 |
---|---|---|
401 | 错误请求 | 服务器不理解请求的语法 |
401 | 未授权 | 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应 |
403 | 禁止 | 服务器拒绝请求 |
404 | 未找到 | 服务器找不到请求的资源 |
-
5xx(服务器错误)
500 | 服务器内部错误 | 服务器遇到错误,无法完成请求 |
---|---|---|
500 | 服务器内部错误 | 服务器遇到错误,无法完成请求 |
501 | 尚未实施 | 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码 |
502 | 错误网关 | 服务器作为网关或代理,从上游服务器收到无效响应 |
503 | 服务不可用 | 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态 |
首部字段(HTTP/1.1)
-
通用首部字段(9个)
首部字段名 | 说明 |
---|---|
Connection | 逐跳首部、连接的管理 |
Date | 创建报文的日期时间 |
Program | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
Cache-Control | 控制缓存的行为 |
-
请求首部字段(19个)
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言(自然语言) |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户的电子邮箱地址 |
Host | 请求资源所在的服务器 |
If-Match | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记(与If-Match相反) |
If-Range | 资源未更新时发送实体Byte的范围请求 |
If-Unmodified-Since | 比较资源的更新时间(与If-Modified-Since相反) |
Max-Forwards | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节范围请求 |
Referer | 对请求中的URI的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP客户端程序的信息 |
-
响应首部字段(9个)
首部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
Content-Disposition | 可以控制返回的资源是下载还是预览(图片) |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
-
实体首部字段(10个)
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体试用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小(单位:字节) |
Content-Location | 替换对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期时间 |
Cookie
也协作Cookies、通常用于web端记录用户身份。
-
工作流程
1. 客户端发送一个http请求到服务器端
Cookie由服务器端生成(定义)并记录保存
2. 服务器端发送一个http响应到客户端,其中包含Set-Cookie头部
客户端保存Cookie
3. 客户端发送一个http请求到服务器端,其中包含Cookie头部
4. 服务器端发送一个http响应到客户端
确认用户身份(权限)以返回不同的资源
-
用途
Cookie在一定程度上解决了http无状态的缺陷。
1. 站点跟踪
2. 识别用户
-
Cookie的特点
1. 不可跨域
域名www.google.com颁发的Cookie不会被提交到域名www.baidu.com去。一二级域名可设置是否互通。
2.Cookie的有效期
有效期可设置。负数为临时Cookie、0为失效。
3.中文编码
中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。
-
Cookie的缺陷
不利于隐私的保护
-
查看Cookie
对于某个单一的网站很简单
控制台输入javascript:alert (document. Cookie)
即可。
如果要查看缓存目录、则需要根据不同系统以及浏览器去查找。
Session
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
需要注意的是、Session会根据Cookie中的特殊字段来确定用户是否被冒充。
-
Session的有效期
由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。
-
Session与Cookie
虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。
Cookie和Session的方案虽然分别属于客户端和服务端,但是服务端的session的实现对客户端的Cookie有依赖关系的,上面我讲到服务端执行session机制时候会生成session的id值,这个id值会发送给客户端,客户端每次请求都会把这个id值放到http请求的头部发送给服务端,而这个id值在客户端会保存下来,保存的容器就是Cookie,因此当我们完全禁掉浏览器的Cookie的时候,服务端的session也会不能正常使用。
参考资料
HTTP 首部字段详细介绍
HTTP首部字段
常见的HTTP状态码(HTTP Status Code)说明
理解Cookie和Session机制
HTTP1.0和HTTP1.1的区别
Http1.1和Http1.0的区别
HTTP/2.0 相比1.0有哪些重大改进
HTTP 2.0 原理详细分析