HTTP协议详细学习

HTTP 协议

0x1 概念

协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信 协议,它允许将超文本标记语言(HTML)文档从W eb服务器传送到客户端的浏览器。
HTTP协议,即超文本传输协议(Hypertext transfer protocol)。是一种详细规定了浏览器和万维网(W W W = World Wide Web)服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。
HTTP协议是用于从W W W 服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它 不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图 形)等。
HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。
在Internet中所有的传输都是通过TCP/IP进行的。HTTP协议作为TCP/IP模型中应用层的协议也不例外。HTTP协议通 常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。如下图所示:

HTTP默认的端口号为80,HTTPS的端口号为443。

0x2 特点

HTTP(超文本传输协议)是用于在客户端和服务器之间传输超文本数据的协议。它是Web通信的基础。以下是HTTP协议的几个关键特点:

  1. 无状态性
    • HTTP协议本身是无状态的,这意味着每次请求都是独立的,服务器不会记住之前的请求信息。每次请求都被视为独立的事务。
  2. 无连接性
    • HTTP协议在默认情况下是无连接的。在一个请求/响应的过程中,客户端和服务器建立连接,处理完请求后连接就会关闭。这意味着每次请求都需要重新建立连接(虽然可以通过持久连接技术(如HTTP/1.1中的Keep-Alive)来减少开销)。

“无状态”和“Connection: keep-alive”之间的区别

1. 无状态性(Stateless)

  • 定义:HTTP协议本身是无状态的,这意味着每次请求都是独立的,服务器不保留任何前一个请求的信息。每次客户端发起请求时,服务器不会记住之前发生的任何事情。
  • 举例:当你在浏览器访问一个网站时,每次请求(比如访问网页、图片或提交表单)都是独立的,服务器不会记住你上一次请求的内容。即使是同一个用户,每次请求都不会携带之前请求的任何信息,除非使用额外的技术(如Session、Cookies)来保持状态。

2. **Connection: keep-alive**:

  • 定义Connection: keep-alive是HTTP协议中一个头部字段,用来表示持久连接(Persistent Connection)。它使得在同一个TCP连接上,可以发送多个HTTP请求和响应,而不需要每次请求都重新建立连接。
  • 作用:通常情况下,在HTTP/1.0中,每个请求/响应都会建立一个新的TCP连接,并且在响应完成后立即关闭连接。而在HTTP/1.1及其之后的版本中,默认启用了Connection: keep-alive,这意味着同一个连接可以复用进行多个请求和响应,直到连接超时或被显式关闭。
  • 举例:当你访问一个网页时,该网页可能包含多个资源(如CSS文件、JavaScript文件、图片等)。如果启用了keep-alive,所有这些资源请求可以通过同一个TCP连接完成,而无需每次都重新建立连接。

区别

  1. 无状态性:是指每个HTTP请求独立,服务器不会保存任何会话信息,客户端每次请求时需要提供所有必要的信息(如身份验证、参数等)。这与“保持连接”的概念不同,因为它强调的是请求之间的独立性,而不是连接的持续性。
  2. **Connection: keep-alive**:是为了优化性能而设计的,它与无状态性并不冲突。keep-alive的目的是减少频繁建立连接的开销,提升响应速度和效率,尤其是在客户端发起多个请求的情况下。然而,它并不改变HTTP协议的无状态性质。即使在启用keep-alive时,每个请求依然是独立的,服务器不会记住前一个请求的上下文。

总结:

  • 无状态性指的是每个请求/响应都是独立的,服务器不保存客户端的任何信息。
  • **Connection: keep-alive**则是为了避免频繁建立和关闭连接而保持连接的持续性,减少开销,但这不意味着HTTP协议本身具备“状态”或“记忆”能力。

0x3 工作流程

一次HTTP操作的四个步骤:

  1. 建立连接
    • 客户端与服务器之间需要建立TCP连接。
    • 只要用户点击一个超级链接,HTTP操作就开始。
  2. 发送HTTP请求
    • 客户端通过已建立的连接向服务器发送请求。
    • 请求的格式包含:
      • 统一资源标识符(URL)
      • 协议版本号(如HTTP/1.1)
      • MIME信息(请求修饰符、客户机信息、可能的内容等)
  3. 服务器响应请求
    • 服务器接收到请求后,返回响应信息。
    • 响应的格式包含:
      • 状态行(协议版本号、成功或错误的状态码)
      • MIME信息(服务器信息、实体信息、可能的内容等)
  4. 客户端显示信息
    • 客户端接收到服务器返回的信息。
    • 通过浏览器显示内容给用户。
    • 客户端与服务器断开连接。

0x4 头域

发出的请求信息格式如下:

  • 请求行,例如GET /images/logo.gif HTTP/1.1,表示从/images目录下请求logo.gif这个文件。
  • (请求)头,例如Accept-Language: en
  • 空行
  • 可选的消息体 请求行和标题必须以作为结尾(也就是,回车然后换行)。空行内必须只有 而无其他空格。在HTTP/1.1协议中,所有的请求头,除post外,都是可选的。

image-20250414170723670

三个部分分别是:请求行、消息报头、请求正文。

0x5 请求方法

请求方法有下面八种

请求方法 描述 常见用途
GET 请求指定的资源,通常用于获取数据。 获取网页、图片、API数据等。
POST 向服务器提交数据,通常用于表单提交或上传数据。 提交表单数据,上传文件,创建资源等。
PUT 用于更新指定的资源,要求请求体包含更新后的完整数据。 更新现有资源,如编辑数据、修改用户信息等。
DELETE 删除指定的资源。 删除服务器上的文件、记录或数据。
HEAD 与GET方法类似,但服务器只返回响应头,不返回响应体。 检查某个资源是否存在、获取资源的元数据等。
OPTIONS 查询服务器支持哪些HTTP方法。 查询服务器支持的请求方法、CORS(跨域资源共享)等。
PATCH 用于局部更新指定的资源,通常只提供需要修改的数据。 更新资源的一部分,例如修改用户资料中的一项字段。
TRACE 回显服务器收到的请求,用于诊断请求链路。 诊断HTTP请求路径,查看中间的代理服务器和客户端之间的通信。
CONNECT 建立一个到目标服务器的隧道,用于加密协议(如HTTPS)。 常用于通过HTTP代理访问加密的内容。

*POST和GET请求的区别

下面是 POSTGET 请求的主要区别:

区别 GET请求 POST请求
数据传输方式 数据通过URL传递,参数附加在URL后面。 数据通过请求体(body)传递,不显示在URL中。
安全性 数据公开,容易被截获,不适合传递敏感信息。 数据不显示在URL中,相对较为安全,但依然需要加密。
缓存 GET请求的结果可以被缓存,适用于只读操作。 POST请求的结果一般不被缓存。
请求大小 GET请求的大小受限于URL的长度,通常约为2048字符。 POST请求没有固定大小限制,理论上可以提交更大的数据。
幂等性 GET请求是幂等的,意味着多次请求不会产生副作用。 POST请求不是幂等的,重复请求可能会创建多个资源或进行多次操作。
使用场景 适用于获取数据、查询等操作。 适用于提交数据、创建或修改资源等操作。
书写形式 URL中包含请求参数,如:GET /search?q=keyword 请求参数包含在请求体中,如:POST /submit
浏览器行为 浏览器会在历史记录中保存GET请求,且可以通过回退按钮重试请求。 浏览器不会保存POST请求的历史记录,用户无法通过回退按钮重新提交。
数据传输容量 受限于URL长度和浏览器/服务器的限制,通常不能传输大量数据。 可以传输大量数据,适合表单提交、文件上传等。

0x6 解决HTTP无状态的问题

HTTP协议本身是无状态的,这意味着每个请求都是独立的,服务器不会保存客户端请求的任何信息。虽然这种设计使得HTTP非常简单和灵活,但在某些场景下,如需要跟踪用户会话(如登录状态、购物车内容等),无状态性会带来一定的挑战。为了解决这个问题,通常会使用以下几种方法来保持状态:

  • 原理:通过在客户端(浏览器)存储小量的数据(称为Cookie)来维持状态。服务器发送一个包含状态信息的Cookie给客户端,客户端在后续的请求中将该Cookie附带在请求头中,从而实现状态的保持。
  • 优点:简单、易于实现,广泛用于会话管理和用户认证。
  • 缺点:客户端存储的容量有限,每个请求都需要携带,可能会影响性能。敏感信息需加密以保证安全。
  • 示例:用户登录网站后,服务器会返回一个包含session ID的Cookie,后续请求中浏览器会携带该Cookie,服务器通过这个ID来识别用户。

示例:

1
Set-Cookie: sessionId=abc123; Path=/; HttpOnly

2. Session

  • 原理:服务器端通过存储会话数据(如数据库、内存等)来保存状态。客户端通过Session ID(通常存储在Cookie中)来标识会话,每次请求时,客户端都会携带这个ID,服务器通过该ID来查找对应的会话数据。
  • 优点:状态存储在服务器端,数据更安全,不会暴露给客户端。
  • 缺点:服务器需要管理会话数据,存储容量受限,需要在服务器端维护会话。
  • 示例:常见的Web框架(如Flask、Django)提供了内建的Session支持,通常通过Cookie传递Session ID。

示例:

1
session['user_id'] = user.id  # 保存用户ID

3. Token(如JWT)

  • 原理:通过使用令牌(Token)来维持会话状态,常见的令牌包括JSON Web Token(JWT)。客户端在每次请求时附带一个加密的Token,Token包含了用户的身份和权限等信息。服务器通过解密Token来验证用户身份和权限。
  • 优点:适用于分布式系统、跨域认证等场景。客户端存储Token(通常存储在localStorage或SessionStorage),无需服务器端存储。
  • 缺点:Token存储在客户端,可能存在被篡改的风险。需要做好Token的安全存储和过期处理。
  • 示例:用户登录后,服务器生成一个JWT,客户端存储该JWT,后续请求携带该Token进行身份验证。

示例:

1
2
3
4
5
{
"user_id": 12345,
"exp": 1628707200,
"iat": 1628610800
}

4. URL参数

  • 原理:通过将状态信息嵌入到URL中,服务器可以通过URL来识别不同的请求。虽然这种方式通常只适用于短期的状态保持(如用户的临时筛选条件),但也有一定的局限性。
  • 优点:简单直观,尤其适用于短期状态传递。
  • 缺点:URL暴露状态信息,不适合存储敏感信息。且长时间或大规模传输状态可能导致URL变长或不易管理。
  • 示例:在URL中传递查询参数来维持状态。

示例:

1
http://example.com/?session_id=abc123

5. Hidden Form Fields

  • 原理:在表单中使用隐藏字段(<input type="hidden">)来传递状态信息,客户端提交表单时,状态信息会随表单一起提交到服务器。这种方式主要用于表单提交时维持状态。
  • 优点:可以将信息随表单提交,适合用于表单处理场景。
  • 缺点:仅适用于表单提交,状态信息暴露在页面源代码中,安全性较差。
  • 示例:通过隐藏表单字段在表单提交时维持状态。

示例:

1
<input type="hidden" name="session_id" value="abc123">

6. Local Storage / Session Storage

  • 原理:HTML5提供的Local StorageSession Storage允许在客户端浏览器中存储数据。Local Storage是持久化存储,而Session Storage只在会话期间有效。通过存储在浏览器中的数据,可以维持状态,尤其适用于单页面应用(SPA)。
  • 优点:存储空间大,数据存储在客户端,无需依赖服务器。
  • 缺点:存储在客户端,安全性差。不能直接与服务器进行交互,需要通过AJAX请求传递数据。
  • 示例:存储用户的主题偏好或认证Token。

示例:

1
localStorage.setItem('user_id', 'abc123');

7. HTTP头(Authorization Header)

  • 原理:通过HTTP请求头中的Authorization字段来传递认证信息(如用户名、密码或Token)。这通常与JWT或OAuth结合使用,客户端在每次请求时将认证信息传递给服务器,服务器验证后返回响应。
  • 优点:适用于API认证,尤其是RESTful架构中的认证和授权。
  • 缺点:需要在每个请求中发送认证信息,可能增加带宽开销。Token泄露时可能被滥用。
  • 示例:在请求头中传递JWT或Bearer Token。

示例:

1
Authorization: Bearer abc123

0x7 URL详解

URL 用于定位互联网上的资源,通常包含以下几个部分:

URL 的基本格式:

1
scheme://host[:port]/path[;url-params][?query-string][#anchor]

1. Scheme(协议)

  • 作用:指定访问资源的协议,如 HTTP、HTTPS、FTP 等。
  • 示例http

2. Host(主机)

  • 作用:指定服务器的地址,可以是 IP 或域名。
  • 示例www.example.com

3. Port(端口)

  • 作用:指定访问服务器时的端口(可选,默认为 HTTP 的 80 端口)。
  • 示例:8080(如果使用非默认端口)

4. Path(路径)

  • 作用:指定资源的具体位置。
  • 示例/images/pic.jpg

5. Query String(查询字符串)

  • 作用:传递给服务器的数据,通常以 ? 开始,多个参数用 & 分隔。
  • 示例?name=John&age=30

6. Anchor(锚点)

  • 作用:页面内部的定位点,用 # 标记。
  • 示例#section1

示例 URL:

1
http://www.example.com/index.html?name=John#about
  • Scheme: http
  • Host: www.example.com
  • Path: /index.html
  • Query String: ?name=John
  • Anchor: #about

0x8 HTTP响应码

这是常见的 HTTP 响应码及其含义的表格:

响应码 类别 含义
100 信息性响应 Continue:客户端应继续请求。
101 信息性响应 Switching Protocols:服务器接受请求,切换协议。
200 成功响应 OK:请求成功,返回请求的数据。
201 成功响应 Created:请求成功,资源已创建。
202 成功响应 Accepted:请求已接受,但尚未处理。
204 成功响应 No Content:请求成功,但没有返回内容。
301 重定向响应 Moved Permanently:资源已永久移动到新位置。
302 重定向响应 Found:资源暂时移动到其他位置。
304 重定向响应 Not Modified:资源未修改,可使用缓存的副本。
400 客户端错误 Bad Request:请求格式错误,服务器无法理解。
401 客户端错误 Unauthorized:未授权,需要身份验证。
403 客户端错误 Forbidden:禁止访问,服务器拒绝请求。
404 客户端错误 Not Found:找不到请求的资源。
405 客户端错误 Method Not Allowed:请求方法不被允许。
408 客户端错误 Request Timeout:请求超时,服务器没有收到完整请求。
500 服务器错误 Internal Server Error:服务器内部错误。
502 服务器错误 Bad Gateway:作为网关或代理的服务器收到无效响应。
503 服务器错误 Service Unavailable:服务器不可用,通常是由于过载或维护。
504 服务器错误 Gateway Timeout:作为网关或代理的服务器未及时收到响应。

这是一些常见的 HTTP 响应码,不同的响应码用于表示不同的请求状态或服务器情况。