目录

HTTP拾技杂谈

HTTP拾技杂谈

HTTP拾技杂谈

简单聊聊HTTP中的那些东西



前言

超文本传输协议(Hypertext Transfer Protocol ,HTTP)是一个标准,定义了Web客户端如何与服务器对话,以及数据如何从服务器传回客户端。尽管通常任务HTTP是一种传输HTML文件以及文件中内嵌图片的方法,但实际上HTTP是一个数据格式。——《java网络编程》


HTTP协议

HTTP连接使用TCP/IP来传输数据。

1.请求从客户端到服务器端的4个步骤

  1. 默认情况下,客户端在80端口与服务器打开一个TCP连接,URL可以指定其他端口

  2. 客户端向服务器发送消息,请求指定路径上的资源。请求分为首部、可选地址、请求数据。

  3. 服务器向客户端回复响应。以响应码开头,后面是包含元数据的首部、一个空行、所请求的文档(数据)或错误消息。

  4. 服务器关闭连接。

    以上就是基本HTTP1.0过程,在HTTP1.1及以后版本中,可以复用TCP连接实现发送多个请求。在1.1中请求和响应可以分为多个块发送。

一般客户端请求如下:

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类型。

最后以空行,或者空行+数据体

服务端响应如下

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在请求和响应的HTTP首部中,由服务器传递到客户端,再从客户端传回服务器。

cookie可以是标识会话ID、购物车、登录凭据等信息,也可以存无意义的值。

要在浏览器设置一个cookie,则需要服务器端在响应中使用Set-Cookie首部行:

HTTP/1.1 200 OK                          # 状态行协议版本 + 状态码 + 原因短语
Content-Type: text/html; charset=UTF-8   # 消息体的格式和编码
Set-Cookie: xxx=dsahjfkeqyowqlf   # 设置cookie

而后,客户端再向同一个服务发送请求:

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机制。