HTTP实用指南
初识
背景知识
HTTP(Hyper Text Transfer Protocol)是一种用于在Web上进行通信的协议。它最早由蒂姆·伯纳斯-李(Tim Berners-Lee)在1989年设计,并在1991年成为互联网标准。HTTP协议的出现是为了支持万维网的发展和传播。
概念
HTTP(Hyper Text Transfer Protocol)是一种应用层协议,用于在Web上进行通信。它定义了客户端和服务器之间的通信规则和数据格式,以实现数据的传输和交互。
HTTP使用请求-响应模型,客户端发送HTTP请求到服务器,服务器处理请求并返回HTTP响应给客户端。请求和响应都由一系列的文本消息组成,以及相关的头部信息。请求消息描述了客户端要求的动作和请求的资源,而响应消息则包含了服务器对请求的回应及所返回的数据。
特点
- 简单可扩展:HTTP协议的设计简单明了,易于理解和实现。它采用了简单的请求-响应模型,请求由客户端发送给服务器,服务器对请求进行处理并发送响应回客户端。此外,HTTP协议还提供了丰富的扩展机制,允许通过添加新的请求方法、响应状态码、头部字段等来满足不同场景的需求。
- 无状态:HTTP协议是无状态的,即服务器不会记录之前的请求和响应信息。每个请求都是独立的,服务器不能直接根据前一个请求的信息判断当前请求的状态。这样设计使得HTTP协议简化了服务端的状态管理,降低了服务器的复杂度,但也带来了一些限制,比如无法直接实现用户会话跟踪,需要借助其他机制实现状态管理。
- 基于TCP协议:HTTP协议是基于TCP协议的应用层协议。TCP提供了可靠的数据传输机制,保证了数据的完整性和顺序性。HTTP利用TCP的可靠性来确保数据的可靠传输,同时也意味着HTTP会受到TCP的一些限制,如长连接中的头阻塞问题。
- 支持多媒体传输:HTTP协议不仅可以传输超文本(HTML),还可以传输图片、音视频等多媒体内容。通过在请求头中指定合适的Content-Type字段,可以告知服务器需要传输的数据类型,并由服务器返回相应的数据。
- 可被代理和缓存支持:HTTP协议允许代理服务器存在,客户端可以通过代理服务器与目标服务器通信。代理服务器可以对请求和响应进行缓存、安全过滤、负载均衡等操作。此外,HTTP还支持客户端和服务器之间的缓存机制,减少重复请求,提高性能。
协议特点
发展历程
- HTTP/0.9(1991年):Tim Berners-Lee在1991年设计了初版的HTTP协议,版本号为0.9。该版本是简单的协议,只支持GET请求方法,响应只返回HTML格式的数据。
- HTTP/1.0(1996年):HTTP/1.0是第一个被广泛使用的HTTP版本。它引入了多种新的功能,如支持多种请求方法(GET、POST、PUT、DELETE等)、引入状态码用于表示请求状态、支持请求头字段等。
- HTTP/1.1(1997年):HTTP/1.1是目前最为广泛使用的HTTP版本。它进一步优化了HTTP/1.0的性能和功能,引入了持久连接、流水线化、缓存、范围请求等特性来提高性能和效率。
- HTTP/2(2015年):HTTP/2是对HTTP/1.1的重大升级,旨在提供更高的性能和效率。它引入了多路复用,允许多个请求共享同一个TCP连接。同时,HTTP/2还支持头部压缩、服务器推送等新特性。
- HTTP/3(预计2020年):HTTP/3是正在开发中的下一个重要版本,也被称为QUIC(Quick UDP Internet Connections)。它采用了基于UDP的传输协议,旨在更进一步提高Web应用的性能和安全性。
报文解析
步骤如下:
- 分离报文:首先需要将原始的HTTP报文根据报文首部与报文体之间的空行进行分离,得到独立的报文首部和报文体。
- 解析报文首部:对报文首部进行解析,按照每行一个头部字段的格式进行处理。可以使用正则表达式或字符串处理函数来解析出每个头部字段的名称和值。
- 解析报文体:根据Content-Type字段的值确定报文体的类型,并进行相应的解析。对于普通的文本内容,可以直接提取出来;对于二进制文件,可以写入到指定的本地文件中。
- 解析URL:如果是请求报文,需要解析URL来获取请求的资源路径、查询参数等信息。可以使用URL解析库或字符串处理函数来解析URL。
- 解析查询参数:对于包含查询参数的URL,可以使用字符串处理函数或解析库来解析出每个查询参数的名称和值。
- 解析状态码:如果是响应报文,需要解析状态行中的状态码和状态短语。可以使用字符串处理函数或正则表达式来提取出状态码和状态短语。
Method
Method方法指的是客户端请求的动作,用于告诉服务器需要执行的操作类型
- GET:用于请求访问已被URI标识的资源,通过URL参数传递数据。GET请求应该是安全和幂等的,即不应对服务器状态产生影响,并且可以多次请求而不造成不同结果。
- POST:用于向服务器提交数据,请求服务器处理并生成新的资源。POST请求是非幂等的,即多次提交会产生不同的结果。
- PUT:用于向服务器上传数据,要求服务器存储请求的数据到指定的URI位置。PUT请求通常用于更新资源,或在指定位置创建新的资源。
- DELETE:用于请求服务器删除指定的资源。
- HEAD:与GET类似,但只请求服务器返回响应头部信息,而不需要整个响应体的内容。主要用于获取资源的元数据,如判断资源是否存在、最后修改时间等。
- OPTIONS:用于获取服务器支持的HTTP方法和可能的资源通信选项。
状态码
HTTP状态码是服务器在处理请求后返回给客户端的数字代码,用于传达请求处理的结果或状态。它由三位数字组成,共分为五个类别:
1xx - 信息性状态码:表示服务器已接收到请求,并且正在处理。常见的状态码有:
100 Continue:服务器已经接收到请求的初始部分,并且还没有被拒绝,继续发送请求的剩余部分。
2xx - 成功状态码:表示请求被成功处理并返回所需信息。常见的状态码有:
200 OK:服务器成功处理了请求。
201 Created:请求成功并在服务器上创建了新资源。
204 No Content:服务器成功处理了请求,但没有返回任何内容。
3xx - 重定向状态码:表示需要进一步操作以完成请求。常见的状态码有:
301 Moved Permanently:永久性重定向,请求的资源已被永久移动到新的URL。
302 Found:临时性重定向,请求的资源临时移动到新的URL。
304 Not Modified:客户端的缓存副本是最新的,不需要重新下载。
4xx - 客户端错误状态码:表示客户端发送的请求有错误。常见的状态码有:
400 Bad Request:服务器无法理解请求,语法格式有误。
403 Forbidden:访问被禁止,服务器理解请求,但拒绝执行该请求。
404 Not Found:请求的资源不存在。
5xx - 服务器错误状态码:表示服务器在处理请求时发生了错误。常见的状态码有:
500 Internal Server Error:服务器遇到错误,无法完成请求。
502 Bad Gateway:充当网关或代理的服务器从上游服务器收到无效响应。
503 Service Unavailable:服务器暂时无法处理请求,通常由于维护或过载。
RESTful API
RESTful API(Representational State Transfer)是一种软件架构风格和设计模式,用于构建分布式系统中的网络服务。基于RESTful API,可以通过HTTP协议进行通信,并以资源的方式对服务进行交互。
特点:
1.每一个URI代表一种资源
2.客户端和服务器之间,传递这种资源的某种表现层
3.客户端通过HTTP method,对服务端资源进行操作,实现“表现层状态转化”
常用请求头
- Accept:指定客户端能够接受的内容类型(MIME类型)。
- Content-Type:指定请求或响应体的内容类型。
- User-Agent:标识客户端类型和版本号,用于服务器识别客户端。
- Authorization:用于身份验证,携带用户凭证,如访问令牌或基本身份验证的用户名和密码。
- Cookie:包含服务器发送过来的Cookie信息,用于保持会话状态。
- Cache-Control:控制缓存机制,指定缓存的行为。
- If-Match:在进行资源更新操作时,检查资源的ETag值是否匹配。
- If-None-Match:用于条件GET请求,检查资源的ETag值是否匹配。
- If-Modified-Since:用于条件GET请求,检查资源的修改时间是否在指定日期之后。
- Content-Length:指定请求或响应体的长度。
- Referer:指示请求的来源URL。
- Origin:指示跨域请求的来源。
- Host:指定服务器的主机名和端口号。
- X-Requested-With:标识请求是通过Ajax发送的。
缓存
强缓存
它通过设置响应头的Cache-Control或Expires字段来指示浏览器在一段时间内直接从缓存中获取资源,而不发送请求到服务器。
常见的强缓存策略有两种:
-
Cache-Control:通过设置Cache-Control字段来控制缓存行为。常见的取值包括:
- public:表示可以被任何中间缓存(如CDN)缓存。
- private:表示仅能被客户端缓存。
- max-age=:指定资源的过期时间,单位为秒。
- no-cache:表示缓存内容需要与服务器验证才能使用,即需要发送请求到服务器进行缓存验证。
- no-store:表示不缓存任何内容,每次请求都必须从服务器获取最新的资源。
-
Expires:通过设置Expires字段来指定资源的过期时间,是一个绝对时间,即一个具体的日期和时间。
当浏览器发起请求时,会首先检查请求的资源是否存在强缓存中。如果存在,并且没有过期(根据Cache-Control中的max-age或Expires字段判断),浏览器就会直接从缓存中获取资源,并且不发送请求到服务器。这样可以极大地提升网页加载速度和减轻服务器负载。
协商缓存
它通过与服务器进行交互,根据资源的状态来决定是否需要发送请求,以及是否使用缓存的资源。
协商缓存的工作原理如下:
- 客户端发送请求到服务器,并在请求头中包含一些用于协商缓存的字段。
- 服务器接收请求,并检查请求头中的协商缓存字段。如果存在且有效,则服务器会进行缓存验证,判断资源的状态是否改变。
- 如果资源没有改变,服务器会返回状态码为304 Not Modified的响应,不返回实际的资源内容。同时,响应头中会包含一些用于缓存控制的字段。
- 客户端收到304响应后,会从缓存中获取资源。
常见的协商缓存字段有两个:
- Last-Modified/If-Modified-Since:服务器在响应中添加Last-Modified字段,表示资源的最后修改时间。而客户端在后续请求中的请求头中添加If-Modified-Since字段,将上次获取资源时的Last-Modified值发送给服务器。服务器根据If-Modified-Since的值判断资源是否改变,如果没有改变,则返回304响应。
- ETag/If-None-Match:服务器在响应中添加ETag字段,表示资源的唯一标识符。客户端在后续请求中的请求头中添加If-None-Match字段,将上次获取资源时的ETag值发送给服务器。服务器根据If-None-Match的值判断资源是否改变,如果没有改变,则返回304响应。
协商缓存机制更加灵活,可以更加准确地判断资源的变化,避免不必要的网络传输和资源重复加载。与强缓存不同,协商缓存可以在多个用户之间共享,提高系统的整体性能和网络效率。
Cookie
Cookie是一种在客户端(通常是浏览器)存储数据的机制,用于跟踪和识别用户。它是通过在HTTP响应头中的Set-Cookie字段发送给客户端,并在后续的请求中通过请求头中的Cookie字段携带数据到服务器。
常见的Cookie属性有以下几个:
- Expires/Max-Age: 用于设置Cookie的过期时间,指定一个绝对时间(Expires)或相对时间(Max-Age,单位为秒)。
- Domain: 用于指定Cookie的有效域,即可以访问该Cookie的域名。
- Path: 用于指定Cookie的有效路径,即可以访问该Cookie的URL路径。
- Secure: 表示只有在HTTPS连接时才能发送该Cookie。
- HttpOnly: 表示该Cookie只能通过HTTP或HTTPS协议发送,不能通过JavaScript访问。
HTTPS
HTTPS(Hypertext Transfer Protocol Secure)是一种通过加密和证书验证来保护通信安全的HTTP协议。它是HTTP的安全版本,使用了SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议来建立加密连接。
HTTPS的主要目的是确保在客户端和服务器之间传输的数据是安全的,防止数据被窃取、篡改或伪造。
特点:
- 数据加密:HTTPS使用SSL/TLS协议对通信的数据进行加密,使得第三方无法截取和解密通信内容。这样可以保护用户的隐私和敏感信息,例如登录凭证、支付信息等。
- 身份验证:HTTPS使用数字证书来验证服务器的身份。证书由受信任的第三方机构(称为CA,Certificate Authority)签发,客户端可以使用证书来确认服务器的真实性。这样可以防止中间人攻击和欺骗。
- 排名优化:搜索引擎(如Google)倾向于对使用HTTPS的网站给予更高的排名权重。这可以提高网站的可见性和流量。
- 信任和用户体验:许多用户会通过浏览器中的地址栏或锁定图标来判断网站的安全性。使用HTTPS可以显示安全的信号,增强用户对网站的信任感。
要启用HTTPS,需要获得服务器证书并在服务器上配置HTTPS服务。通常,证书是从CA购买并用于特定域名的。然后,将证书安装在服务器上,并将服务器配置为侦听HTTPS请求。客户端在访问该网站时,会与服务器进行握手,并建立加密通道。