HTTP 工作流程&请求&响应 - 面试常问

文章目录

HTTP 工作流程

建立HTTP连接的完整流程涉及多个网络层次和协议。以下是该过程中的关键步骤:

  1. DNS解析
    当你在浏览器输入一个URL并按下回车时,例如 http://www.example.com,浏览器首先需要找出服务器的实际IP地址,这是通过DNS(域名系统)完成的。
  • 浏览器检查缓存:浏览器首先检查自己的DNS缓存中是否有这个域名的记录,如果有,这个过程就会快很多。
  • 操作系统DNS缓存:如果浏览器缓存中没有记录,浏览器会检查操作系统的DNS缓存。
  • 路由器DNS缓存:如果前面的缓存都没有找到,请求会发送到本地网络的路由器,它可能有自己的DNS缓存。
  • ISP DNS服务器:如果还是没有找到记录,请求会发送到ISP(互联网服务提供商)的DNS服务器。
  • 根、顶级域和权威DNS服务器:如果ISP的DNS服务器也不能解析该域名,则会进行一系列的查询到根DNS服务器、顶级域DNS服务器,最后到域名的权威DNS服务器,直到找到域名对应的IP地址。
  1. TCP/IP连接建立
    一旦得到服务器的IP地址,浏览器会建立到服务器的TCP连接。这通常通过三次握手过程完成:
  • SYN:客户端发送一个SYN(同步序列编号)数据包到服务器,询问服务器是否开放端口(如HTTP的80端口或HTTPS的443端口)。
  • SYN-ACK:服务器如果开放该端口,会返回一个SYN-ACK(同步-确认)数据包作为应答。
  • ACK:客户端收到服务器的SYN-ACK响应后,会发送一个ACK(确认)数据包,这样TCP连接就建立了。
  1. 发送HTTP请求
    通过TCP连接,客户端可以发送一个HTTP请求。请求通常包含:
  • 请求行(如 GET /index.html HTTP/1.1)
  • 请求头(如 Host: www.example.com、User-Agent: Mozilla/5.0 等)
  • 空行,标记请求头的结束
  • 请求体(对于GET请求来说通常为空)
  1. 服务器处理请求并生成响应
    服务器接收到HTTP请求后,会进行处理。这个过程可能包括查询数据库、读取文件系统或执行程序代码等操作。处理完毕后,服务器会生成一个HTTP响应发送回客户端,包括:
  • 状态行(如 HTTP/1.1 200 OK)
  • 响应头(如 Content-Type: text/html、Content-Length: 1234 等)
  • 空行,标记响应头的结束
  • 响应体,即请求资源的实际内容
  1. 客户端处理响应

    客户端接收并解析服务器的HTTP响应。如果是网页内容,浏览器会解析HTML、加载CSS、JavaScript和图像资源,然后渲染页面。如果状态码指示错误(如404表示未找到资源),浏览器可能会显示错误信息。

  2. 连接关闭

    在HTTP/1.0中,每个HTTP请求/响应周期后,连接默认会关闭。而在HTTP/1.1及更高版本中,可以通过在请求头部或响应头部中设置Connection: keep-alive来保持连接打开,以便复用TCP连接进行后续的HTTP请求。在HTTP/2中,连接默认保持开放,且可以在单个连接上并行传输多个请求和响应。

对于HTTPS连接(HTTP over SSL/TLS),流程基本相同,但在发送HTTP请求和接收HTTP

请求和响应格式

HTTP请求和响应遵循一定的标准格式,它们由起始行、头部字段和可选的消息正文组成。下面详细介绍这些组成部分:

HTTP请求格式

请求行:

包含HTTP方法、请求的资源URI和HTTP版本。

例如:GET /index.html HTTP/1.1

请求头部字段:

提供请求的元数据,如客户端信息、格式偏好等。

常见请求头部字段包括:

  • Host: 请求的目标主机和端口。
  • User-Agent: 发出请求的客户端信息。
  • Accept: 客户端能够处理的媒体类型。
  • Accept-Language: 客户端的首选语言。
  • Connection: 控制连接的选项,如keep-alive。
  • Cookie: 服务器设置的cookie信息。
  • Authorization: 认证凭据,如基本认证或令牌。
  • Content-Type: 请求正文的媒体类型(通常用于POST和PUT请求)。
  • Content-Length: 请求正文的长度(字节)。

空行:

  • 请求头和消息正文之间的空行,标识头部结束。

消息正文(请求正文):

包含发送给服务器的数据,如表单数据或文件上传。

不是所有HTTP方法都包含消息正文,例如GET和HEAD请求就没有正文。

HTTP响应格式

状态行:

包含HTTP版本、状态码和状态文本。

例如:HTTP/1.1 200 OK

响应头部字段:

提供响应的元数据,如内容类型、缓存策略等。

常见响应头部字段包括:

  • Content-Type: 响应正文的媒体类型,如text/html。
  • Content-Length: 响应正文的长度(字节)。
  • Set-Cookie: 服务器向客户端设置cookie。
  • Cache-Control: 缓存控制指令。
  • Expires: 响应过期的日期和时间。
  • Server: 服务器软件信息。
  • Location: 用于重定向到另一个URL。

空行:

响应头和消息正文之间的空行,标识头部结束。

消息正文(响应正文):

包含服务器返回的数据,如HTML文档、图片等。

HTTP方法

  • GET: 请求指定的资源。
  • POST: 向指定资源提交数据进行处理,如表单数据。
  • PUT: 上传指定资源的更新内容。
  • DELETE: 删除指定的资源。
  • HEAD: 与GET相同,但只返回响应头,不返回正文。
  • OPTIONS: 描述指定资源的通信选项。
  • PATCH: 对资源应用部分修改。

HTTP状态码

2xx一般代表成功,3xx代表重定向,4xx代表客户端错误,5xx代表服务端错误

  • 200 OK: 请求成功,并在响应正文中返回请求的数据。
  • 201 Created: 请求成功,并且服务器创建了新的资源。
  • 204 No Content: 请求成功,但没有新的信息返回。
  • 301 Moved Permanently: 请求的资源已永久移动到新位置。
  • 302 Found: 请求的资源临时移动到其他URI。
  • 400 Bad Request: 服务器不能或不会处理请求,由于客户端的错误(如请求语法不正确)。
  • 401 Unauthorized: 请求要求用户的身份认证。
  • 403 Forbidden: 服务器理解请求客户端的请求,但是拒绝执行此请求。
  • 404 Not Found: 服务器找不到请求的资源。
  • 500 Internal Server Error: 服务器内部错误,无法完成请求。
  • 503 Service Unavailable: 服务器不可用,通常是由于过载或维护。

常用HTTP头部字段

Content-Type: 指定消息正文的MIME类型

请求实例

shell 复制代码
POST /activity/report HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 105
Content-Type: application/json; charset=UTF-8
Cookie: uuid_tt_dd=10_21050577010-1710584908789-747353; c_segment=9; log_Id_view=6636
Host: mp-activity.csdn.net
Origin: https://blog.csdn.net
Referer: https://blog.csdn.net/namedlock?spm=1011.2415.3001.5343
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

响应实例

shell 复制代码
HTTP/1.1 200 OK
Date: Mon, 18 Mar 2024 11:16:07 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: https://blog.csdn.net
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 86400
Access-Control-Allow-Credentials: true
Server: elb

{
    "code": 200,
    "message": "请求成功",
    "data": {
        "matched": false,
        "operationCommand": null,
        "ext": null,
        "activityId": null,
        "activityTitle": null
    }
}

HTTP 如何实现状态管理

HTTP 是一个无状态的协议,意味着每个请求都是独立的,服务器默认不会记住之前的请求。为了跨多个请求或浏览器会话维持用户状态,通常使用 Cookies 和 Session 机制。

Cookies的工作原理

Cookies 是服务器发送到用户浏览器的一小段数据,并由浏览器存储。每当同一用户从浏览器再次发送请求到服务器时,浏览器会将之前存储的Cookie数据一起发送到服务器。这样,服务器就可以识别并维持用户状态了。

设置Cookies:

当浏览器请求服务器时,服务器可以通过设置HTTP响应头Set-Cookie来创建一个Cookie。

例如:Set-Cookie: sessionid=abc123; Path=/; Expires=Wed, 09 Jun 2021 10:18:14 GMT

浏览器存储Cookies:

浏览器接收到Set-Cookie后,会保存Cookie数据,并根据服务器指定的参数(如有效期、路径、域等)来决定何时发送Cookie。

发送Cookies:

在后续对同一域名的请求中,浏览器会自动在HTTP请求头中包含对应的Cookie数据。

例如:Cookie: sessionid=abc123

服务器读取Cookies:

服务器通过读取请求头中的Cookie数据,可以识别发送请求的用户,并提供个性化的服务。

Session的工作原理

Session 是另一种在服务器端跟踪状态的机制。每个用户第一次访问服务器时,服务器都会创建一个唯一的Session,并将其ID(通常是一个随机字符串)存储在Cookie中发送给用户。服务器会保存每个Session的状态数据,如用户登录信息、购物车内容等。

创建Session:

用户首次访问服务器时,服务器创建一个Session,并生成一个唯一的Session ID。

存储Session ID:

Session ID 通过Cookie发送给用户浏览器存储,或者通过URL重写等其他方式传递。

客户端请求和Session ID:

客户端每次发送请求都会包含这个Session ID,服务器通过Session ID 来识别用户和状态。

服务器使用Session:

服务器根据Session ID 找到对应的Session数据,进行相应的处理。

安全问题

虽然Cookies和Session是维护状态的有效手段,但它们也带来了安全问题:

Cookie盗用:

如果攻击者获取到用户的Cookie信息,可以伪装成该用户与服务器交互。

  • 跨站脚本攻击(XSS):
    如果网站存在XSS漏洞,攻击者可以注入恶意脚本,窃取用户Cookie。
  • 跨站请求伪造(CSRF):
    如果网站没有CSRF保护,攻击者可以在用户不知情的情况下,利用用户的登录状态进行恶意操作。

安全属性:

  • 应设置Cookie的Secure属性,确保仅在HTTPS连接中发送Cookie。
  • 应设置Cookie的HttpOnly属性,防止JavaScript访问Cookie。

为了保护用户数据和维护会话安全,开发者需要实施合适的安全措施,如使用HTTPS保护数据传输,为Cookie设置安全属性,防范XSS和CSRF等网络攻击。同时,敏感数据如身份认证信息不应直接存储在Cookie中,而应使用Session机制在服务器端安全地管理。

安全性

HTTP协议本身是不加密的,传输过程中的数据可以被拦截和篡改,这导致了安全隐患。为了提高通信安全性,采用了HTTPS(HTTP Secure)协议,它是HTTP协议的安全版本。HTTPS在HTTP和TCP之间加入了一个安全层,通常是SSL(安全套接层)或TLS(传输层安全性),为数据传输提供了加密、身份验证和数据完整性保护。

加密

HTTPS通过SSL/TLS加密数据,确保传输过程中的数据隐私和安全。加密过程包括两个主要步骤:

密钥交换:

客户端和服务器通过一种称为密钥交换算法的方式来建立一个共享的秘密密钥,这个过程一般使用不对称加密技术。最著名的密钥交换算法是RSA,现代实现还可能采用ECDHE(椭圆曲线迪菲-赫尔曼密钥交换)等更安全的方法。

对称加密:

一旦客户端和服务器拥有了共享的秘密密钥,它们就可以使用对称加密算法来加密通信中的数据。对称加密算法(如AES)使用相同的秘密密钥对数据进行加密和解密,它们较不对称加密算法更高效。

身份验证

SSL/TLS还提供了服务器(有时也包括客户端)的身份验证机制。在建立安全连接之前,服务器会向客户端提供一个由可信第三方机构(证书颁发机构,CA)签发的公钥证书。

公钥证书包含了服务器的公钥、证书颁发机构的签名、证书的有效期等信息。

客户端可以验证证书的合法性,确保正在通信的服务器是合法的而不是中间人攻击的伪装服务器。

数据完整性

除了加密和身份验证,SSL/TLS还确保了数据在传输过程中的完整性没有被破坏。通过使用消息摘要算法(如SHA-256)和消息认证码(MAC),接收方可以检测数据在传输过程中是否被篡改。

HTTPS的使用

要使用HTTPS,网站运营者需要向CA申请证书,并安装到服务器上。当用户访问网站时,浏览器和服务器之间会自动进行SSL/TLS握手过程,建立安全连接。

性能考虑

虽然SSL/TLS确保了数据传输的安全性,但相较于裸露的HTTP,它引入了额外的性能开销:

握手过程需要额外的往返时间(RTT)。

加密和解密数据需要计算资源。

不过,随着计算能力的增强和协议的优化(如TLS 1.3的推出),HTTPS的性能差距与HTTP已经大大缩小。

结论

HTTPS已经成为现代互联网的一个基本要求,特别是对于涉及敏感信息传输(如电子商务、在线银行以及任何形式的用户登录)的网站。搜索引擎和浏览器厂商也都在推动HTTPS的使用,比如Google Chrome浏览器标记所有非HTTPS网站为不安全。

进一步阅读和参考资源

HTTP协议是Web开发的基础,了解其工作原理对于任何网络应用开发人员都是至关重要的。以下是一些HTTP协议学习和参考资源,可以帮助你深入了解并掌握HTTP协议的各个方面:

官方文档和规范

书籍

  • "HTTP: The Definitive Guide" by David Gourley and Brian Totty:
    一本经典的书籍,全面深入地介绍了HTTP协议。
  • "High Performance Browser Networking" by Ilya Grigorik (O'Reilly):
    介绍了网络协议的性能相关方面,包括HTTP/2和WebSocket。
  • "HTTP/2 in Action" by Barry Pollard:
    深入探讨了HTTP/2协议的特性和实现。
  • "Web Performance in Action" by Jeremy L. Wagner:
    讲解了如何利用HTTP协议提高网站性能。
    教程和在线课程

开发工具

  • Postman:
    一个用于构建API和测试HTTP请求的强大工具。
    https://www.postman.com/
  • Wireshark:
    网络协议分析器,可以捕获和分析HTTP通信数据。
    https://www.wireshark.org/
  • cURL:
    命令行工具,支持多种协议,包括HTTP,常用于发送请求和测试。
    https://curl.se/
  • Google Chrome Developer Tools:
    浏览器内置的开发者工具,可以查看HTTP请求和响应,分析性能等。

社区和论坛

  • Stack Overflow:
    一个活跃的开发者社区,可以找到关于HTTP协议和网络通信的讨论和问题。
    https://stackoverflow.com/
  • IETF HTTP Working Group:
    讨论和制定HTTP协议标准的官方工作组。
    https://httpwg.org/

通过这些资源,你可以系统地学习HTTP协议的基础知识,掌握其进阶内容,以及保持对最新发展的了解。对于实践应用,实际编码和使用开发

相关推荐
Lee川9 小时前
优雅进化的JavaScript:从ES6+新特性看现代前端开发范式
javascript·面试
Lee川12 小时前
从异步迷雾到优雅流程:JavaScript异步编程与内存管理的现代化之旅
javascript·面试
晴殇i14 小时前
揭秘JavaScript中那些“不冒泡”的DOM事件
前端·javascript·面试
绝无仅有15 小时前
Redis过期删除与内存淘汰策略详解
后端·面试·架构
绝无仅有15 小时前
Redis大Key问题排查与解决方案全解析
后端·面试·架构
AAA梅狸猫16 小时前
Looper.loop() 循环机制
面试
AAA梅狸猫16 小时前
Handler基本概念
面试
Wect16 小时前
浏览器缓存机制
前端·面试·浏览器
不可能的是16 小时前
前端 SSE 流式请求三种实现方案全解析
前端·http
掘金安东尼17 小时前
Fun with TypeScript Generics:玩转 TS 泛型
前端·javascript·面试