走进 HTTP 协议
简介
HTTP协议(超文本传输协议),是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间相互通信的规则,也是基于TCP/IP的应用层协议以及数据传送协议。
特征
- 无状态性:指每个请求和响应之间都是相互独立的,服务器不会保存客户端的状态信息。而web应用是有状态的。
- 请求响应:客户端发送请求给服务器,服务器处理请求并返回响应。其中请求方法包括HTTP方法(GET,POST,PUT,DELETE等)和资源路径组成;响应方法包含状态码(200,404等)、头部信息和数据。
GET / HTTP/1.1
Host: www.example.com
User-Agent: xxxxxxxx
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
// HTTP响应
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 100
Date: Sat, 14 Aug 2023 10:00:00 GMT
Server: ExampleServer/1.0
<!doctype html> <html lang="zh-cn"><...
- 简单可扩展:HTTP 允许通过添加自定义的头部字段(Headers)来扩展其功能。这使得开发者可以定义和传递自定义的元数据。
请求/响应报文
method 请求方法
| 请求方法 | 说明 | 请求行 |
|---|---|---|
| GET(安全的、幂等) | 用于请求指定资源的信息。请求行中的方法是 GET,没有请求体,数据通过 URL 传递。 | GET /example.html HTTP/1.1 |
| POST | 用于向服务器提交数据,可能会引起服务器状态变化。请求体中包含提交的数据。 | POST /submit-form HTTP/1.1 |
| PUT(幂等) | 用于请求服务器存储一个资源,如果资源已存在,则更新该资源。请求行中的方法是 PUT,请求体中包含要存储的数据。 | PUT /update-resource HTTP/1.1 |
| DELETE(幂等) | 用于请求删除指定的资源。请求行中一般没有请求体。 | DELETE /delete-resource HTTP/1.1 |
| HEAD(安全的、幂等) | 类似于 GET,但服务器只返回头部信息,不返回实际内容。用于检查资源的元数据。 | HEAD /resource-info HTTP/1.1 |
| CONNECT | 用于建立网络连接,通常用于代理服务器。 | CONNECT www.example.com:443 HTTP/1.1 |
| OPTIONS(安全的、幂等) | 用于请求服务器支持的通信选项,如支持的方法和头部信息。 | OPTIONS /supported-options HTTP/1.1 |
| TRACE | 用于在网络路径上追踪请求和响应,主要用于诊断。 | TRACE /trace-path HTTP/1.1 |
| PATCH | 用于对资源进行局部修改。 | PATCH /modify-resource HTTP/1.1 |
安全:不会修改服务器的数据的方法:GET HEAD OPTIONS 幂等:同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的,所有safe的方法都是idempotent的:GET HEAD OPTIONS PUT DELETE
状态码
- 1xx 表示请求已接收,继续处理
- 2xx 表示成功
- 3xx 表示需要进一步操作
- 4xx 表示浏览器方面出错
- 5xx 表示服务器方面出错
常见状态码:
| 状态码 | 说明 | 使用场景 |
|---|---|---|
| 200 OK | 表示请求成功,服务器成功处理了客户端的请求 | 通常用于 GET 请求成功返回资源、POST 请求成功创建资源等情况 |
| 201 Created | 表示请求成功,并且服务器创建了新资源 | 通常用于 POST 请求成功创建新资源时返回 |
| 401 Unauthorized | 表示客户端未经身份验证或验证失败,无权访问请求的资源 | 需要用户登录或提供有效身份验证的情况 |
| 404 Not Found | 表示请求的资源在服务器上未找到 | 请求的URL路径不存在 |
| 502 Bad Gateway | 表示服务器作为网关或代理,从上游服务器接收到无效的响应 | 代理服务器转发请求时发生错误 |
请求头
| 请求头 | 说明 | 示例 |
|---|---|---|
| Content-Type | 用于指定请求体的媒体类型(如 JSON、XML、表单等) | application/x-www-form-urlencoded |
| Accept | 用于指定客户端所期望接收的响应内容类型 | Accept: text/html, application/xhtml+xml, application/xml;q=0.9, /;q=0.8 |
| Cookie | 用于在请求中发送保存在客户端的 Cookie 信息 | Cookie:sessionID=abcdef12345; userID=54321 |
| User-Agent | 用于标识发起请求的用户代理(浏览器、应用程序等)的信息 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 |
响应头
| 响应头 | 说明 | 示例 |
|---|---|---|
| Content-Type | 服务器返回的实体内容的类型 | Content-Type: application/json |
| Cache-Control | 用于指定响应的缓存控制行为,控制客户端和中间缓存如何缓存响应 | Cache-Control: max-age=3600 |
| Last-Modified | 用于表示资源的最后修改时间,用于缓存验证,配合 If-Modified-Since 使用 | Last-Modified: Sat, 14 Aug 2023 10:00:00 GMT |
| ETag | 用于表示资源的标识符,用于缓存验证,配合 If-None-Match 使用 | ETag:"abc123" |
cookie
| 响应头 | 含义 |
|---|---|
| Name=value | 各种cookie的名称和值 |
| Expires=Date | Cookie 的有效期,缺省时Cookie仅在浏览器关闭之前有效 |
| Path=Path | 限制指定Cookie 的发送范围的文件目录,默认为当前 |
| Domain=domain | 限制cookie生效的域名,默认为创建cookie的服务域名 |
| secure | 仅在HTTPS 安全连接时,才可以发送Cookie |
| HttpOnly | JavaScript 脚本无法获得 |
| CookieSameSite=None Strict Lax | None同站、跨站请求都可发送;Strict 仅在同站发送;Lax允许与级导航一起发送,并将与第三方网站发起的GET请求一起发送 |
HTTP 框架的设计与实现
HTTP框架是用于简化开发者处理HTTP请求和响应的工具集合。设计一个高效的HTTP框架需要考虑以下几个方面:
-
路由(Routing):HTTP请求的URL需要与代码中的处理逻辑对应起来。路由系统负责将特定URL映射到相应的处理函数,实现请求的分发。
-
中间件(Middleware):中间件是在请求到达处理函数之前或之后执行的代码。它可以用于执行通用逻辑,如身份验证、日志记录、错误处理等。
-
请求解析与处理:HTTP请求包括方法、URL、头部信息和正文数据。框架需要解析这些信息,并将它们提供给处理函数。处理函数执行后,框架还需要将响应数据打包成HTTP响应格式。
-
模板引擎:有时候需要动态生成HTML等内容,模板引擎允许开发者将数据嵌入到模板中,生成最终的响应内容。
-
错误处理:框架应该能够捕获处理函数中的错误,并返回适当的错误响应。这有助于调试和提供友好的用户体验。
性能修炼之道与企业实践
高性能的HTTP框架在实际企业应用中尤为重要。以下是提升性能的几个关键点:
-
并发处理:服务器需要能够同时处理多个请求,采用异步处理或多线程技术可以提高并发性能。
-
连接池:维护一个可重用的连接池,减少频繁的连接和关闭操作,降低资源开销。
-
缓存:合理使用缓存可以减轻服务器负担,加速响应速度。缓存可以分为客户端缓存和服务器端缓存。
-
负载均衡:将请求分发到不同的服务器上,避免单一服务器过载,提高系统整体性能和稳定性。
-
数据库优化:数据库是性能瓶颈之一,使用数据库连接池、索引优化等手段可以提升数据库查询效率。
-
CDN加速:使用内容分发网络(CDN)可以将资源缓存到全球各地的服务器上,加速用户访问速度。