HTTP拾技杂谈
简单聊聊HTTP中的那些东西
文章目录
前言
超文本传输协议(Hypertext Transfer Protocol ,HTTP)是一个标准,定义了Web客户端如何与服务器对话,以及数据如何从服务器传回客户端。尽管通常任务HTTP是一种传输HTML文件以及文件中内嵌图片的方法,但实际上HTTP是一个数据格式。------《java网络编程》
HTTP协议
HTTP连接使用TCP/IP来传输数据。
1.请求从客户端到服务器端的4个步骤
- 默认情况下,客户端在80端口与服务器打开一个TCP连接,URL可以指定其他端口
- 客户端向服务器发送消息,请求指定路径上的资源。请求分为首部、可选地址、请求数据。
- 服务器向客户端回复响应。以响应码开头,后面是包含元数据的首部、一个空行、所请求的文档(数据)或错误消息。
- 服务器关闭连接。
以上就是基本HTTP1.0过程,在HTTP1.1及以后版本中,可以复用TCP连接实现发送多个请求。在1.1中请求和响应可以分为多个块发送。
一般客户端请求如下:
java
POST /api/data HTTP/1.1 # 请求行(方法 + URI + HTTP版本)
Host: www.example.com # 目标主机(必需首部)
User-Agent: Mozilla/5.0 # 客户端标识
Content-Type: application/json # 消息体格式说明
Content-Length: 27 # 消息体字节长度(必需首部)
Accept: application/json # 期望的响应格式
Authorization: Bearer abc123 # 认证令牌
Connection: keep-alive # 连接控制
#注意这里的空一行是标准
{"key": "value", "num": 42} # 消息体(实际传输的数据)
第一行为请求行,包括方法、从服务器获取资源路径以及HTTP版本。
其他则是以 Key:Value组成的信息。
像User-Agent代表浏览器版本,host服务器名,Accept,告诉服务器,客户端可以处理什么样的数据(定义服务器返回格式)。
这些类型统称为MIME类型,分为两级:类型和子类型。例如:application/json
text/*
image/*
application/*
...等
当然也可以自定义非标准的定制类型和子类型,只要以x-开头。例如flash文件,使用application/x-shockwave-flash类型。
最后以空行,或者空行+数据体
服务端响应如下
java
HTTP/1.1 200 OK # 状态行(协议版本 + 状态码 + 原因短语)
Server: nginx/1.18.0 # 服务器软件及版本
Date: Fri, 13 Oct 2023 05:30:15 GMT # 响应生成时间
Content-Type: text/html; charset=UTF-8 # 消息体的格式和编码
Content-Length: 1234 # 消息体的字节长度
Connection: keep-alive # 连接控制(保持活跃)
Cache-Control: max-age=3600 # 缓存策略(有效期1小时)
ETag: "abc123xyz" # 资源版本标识符
Last-Modified: Mon, 09 Oct 2023 12:00:00 GMT # 资源最后修改时间
<!DOCTYPE html> # 空行(分隔首部和消息体)
<html> # 消息体(实际返回的内容)
<head><title>Example Page</title></head>
<body><h1>Hello World</h1></body>
</html>
第一行表示服务器使用的协议HTTP1.1,紧跟一个响应码。其他首部行则指出请求的日期、消息体字节长度等
2.Keep-Alive
在HTTP请求的首部中大家是否注意到Keep-Alive,他表示可以重用一个socket:
Connection:Keep-Alice。
在HTTP1.0会为每个请求打开一个新的连接,而这样打开和关闭消耗的资源远远大于实际传输数据的开销。所以在HTTP1.1以后就默认支持,复用socket连接,如果需要关闭则使用上述key-value显示控制。
- 在java中可以通过http.keepAlive控制true/false,来控制socket复用
- http.maxConnections可以表示希望同时打开的socket的数量,来保证服务器不会被大量连接冲崩溃。
HTTP方法
HTTP服务器的遵循请求-响应模式:无状态请求+无状态响应。
HTTP的方法主要有4个:
POST、GET、PUT、DELETE
对于这些方法的使用,再谈谈几点容易被忽略的细节:
- GET方法获取一个资源,它没有副作用,如果失败可以反复执行,而不用担心有什么问题
- GET输出可能会被缓存,可以通过首部取消缓存进行禁用
- PUT方法表示将资源上传到服务器,但它具有幂等性。重复该方法也不用担心是否失败,两次将同一个文档放在同一个位置并不影响。
- DELETE与PUT一样具有幂等性,重复执行,也只会将资源删除一次。
- POST是最常用的方法,POST要用于不能重复的不安全的操作,如完成一个交易。
Cookie
很多网站使用一些小文本串 在连接之间存储持久的客户端状态 ,这些称为cookie。
cookie在请求和响应的HTTP首部中,由服务器传递到客户端,再从客户端传回服务器。
cookie可以是标识会话ID、购物车、登录凭据等信息,也可以存无意义的值。
要在浏览器设置一个cookie,则需要服务器端在响应中使用Set-Cookie首部行:
java
HTTP/1.1 200 OK # 状态行(协议版本 + 状态码 + 原因短语)
Content-Type: text/html; charset=UTF-8 # 消息体的格式和编码
Set-Cookie: xxx=dsahjfkeqyowqlf # 设置cookie
而后,客户端再向同一个服务发送请求:
java
GET /index.html HTTP/1.1 # 请求行(方法 + URI + HTTP版本)
Host: www.example.com # 目标主机(必需首部)
Cookie:cart = dsahjfkeqyowqlf #cookie要与服务器给的一致
当然服务器可以设置不止一个cookie,可以有多个Set-Cookie,用于控制过期时间、路径、端口、值等信息。
默认情况下,cookie来自哪个服务器则应用于哪个服务器。网站也可以指示一个cookie用于整个子域,例如从www.foo.example.com响应的:
Set-Cookie:user = elharo;Domain=.foo.example.com
表示浏览器除了可以用cookie返回最初的www.foo.example.com,还可发送给*.foo.example.com
当然还可以缩小它的使用域
例如:Set-Cookie: user=elharo; Path=/restricted,表示请求服务器上子树/restricted,可以。而相同网站的其他目录中就不能使用这个cookie。
在Set-Cookie中使用expires = Wdy, DD-Mon-YYYY HH:MM:SS GMT 可以设置cookie的过期时间。
设置Max-Age = 3600 ,则表示3600秒后过期,此时浏览器会从缓存中删除这些cookie。
总结
本章节介绍了HTTP协议是现代Web通信的核心,其设计简洁高效,支持多种请求方法和数据格式,并通过Cookie机制实现了客户端状态的持久化。随着HTTP版本的演进,连接复用等优化机制进一步提升了通信性能。本文详细介绍了HTTP协议的基本原理、请求响应格式、方法特性以及Cookie机制。