前言
在青训营接触 http 协议后 该篇主要整理初认识 http 时的一些概念和内容分享
HTTP 协议
基本概念
协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从 Web 服务器传送到客户端的浏览器。
一个完整的 HTTP 请求过程
- 域名解析(此处涉及 DNS 的寻址过程)
- 发起 TCP 的 3 次握手
- 建立 TCP 连接后发起 http 请求
- 服务器响应 http 请求,浏览器得到 html 代码
- 浏览器解析 html 代码,并请求 html 代码中的资源(如 js、css、图片等,此处可能涉及 HTTP 缓存)
- 浏览器对页面进行渲染呈现给用户(此处涉及浏览器的渲染原理)
URL 详解
URL(Uniform Resource Locator) 地址用于描述一个网络上的资源, 基本格式如下:
schema://host[:port#]/path/.../[?query-string][#anchor]
包括:
- scheme: 指定低层使用的协议(例如:http, https, ftp)
- host: HTTP 服务器的 IP 地址或者域名
- port#: HTTP 服务器的默认端口是 80,这种情况下端口号可以省略。如果使用了别的端口,必须指明,例如 www.cnblogs.com:8080/
- path: 访问资源的路径
- query-string: 发送给 http 服务器的数据
- anchor: 锚
HTTP 消息的结构
Request 请求
- Request line
- 包括:请求方法、请求的资源、HTTP 协议的版本号
- Request header
- 包括:Cache 头域、Client 头域、Cookie/Login 头域、Entity 头域、Miscellaneous 头域、Transport 头域等
- 空行
- Request body
Response 响应
- Response line
- 包括:HTTP 协议的版本号、状态码、消息
- Response header
- 包括:Cache 头域、Cookie/Login 头域、Entity 头域、Miscellaneous 头域、Transport 头域、Location 头域等
- 空行
- Response body
对于无论是 Request 还是 Response 的 header 头部,每个字段都需要去理解的,大家平时可多留意一下浏览器的请求。
状态码
HTTP/1.1 中定义了 5 类状态码, 状态码由三位数字组成,第一个数字定义了响应的类别。
| 状态码 | 类别 | 表达内容 |
|---|---|---|
| 1XX | 提示信息 | 表示请求已被成功接收,继续处理 |
| 2XX | 成功 | 表示请求已被成功接收,理解,接受 |
| 3XX | 重定向 | 要完成请求必须进行更进一步的处理 |
| 4XX | 客户端错误 | 请求有语法错误或请求无法实现 |
| 5XX | 服务器端错误 | 服务器未能实现合法的请求 |
常见状态码:
- 200 OK
- 302 Found 重定向
- 304 Not Modified 缓存
- 400 Bad Request 客户端请求与语法错误/403 Forbidden 服务器拒绝提供服务/404 Not Found 请求资源不存在
- 500 Internal Server Error 服务器发生了不可预期的错误/503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常
请求方法
常用方法:
GET/POST/PUT/DELETE/OPTION- 理解 GET 和 POST 的区别:包括是否有 body、长度限制、是否可缓存等等
HTTP 的特性
HTTP 是一个属于应用层的面向对象的协议,HTTP 协议一共有五大特点:
- 支持客户/服务器模式;
- 简单快速;
- 灵活;
- 无连接;
- 无状态。
无连接的 HTTP
无连接
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。
采用这种方式可以节省传输时间。
Keep-Alive
随着时间的推移,网页变得越来越复杂,里面可能嵌入了很多图片,这时候每次访问图片都需要建立一次 TCP 连接就显得很低效。后来,Keep-Alive 被提出用来解决这效率低的问题。
Keep-Alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 功 能避免了建立或者重新建立连接。
长连接
实现长连接有几个方式:ajax 轮询、long pull、websocket 等。
Websocket 为持久化协议,基于 HTTP 协议(借用 HTTP 协议完成一部分握手)。
无状态的 HTTP
无状态
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是,发送完,不会记录任何信息。
HTTP 协议这种特性有优点也有缺点,优点在于解放了服务器,每一次请求“点到为止”不会造成不必要连接占用,缺点在于每次请求会传输大量重复的内容信息。
客户端与服务器进行动态交互的 Web 应用程序出现之后,HTTP 无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。
于是,两种用于保持 HTTP 连接状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session。
Cookie
Cookie 可以保持登录信息到用户下次与服务器的会话,换句话说,下次访问同一网站时,用户会发现不必输入用户名和密码就已经登录了(当然,不排除用户手工删除 Cookie)。
而还有一些 Cookie 在用户退出会话的时候就被删除了,这样可以有效保护个人隐私。
Session
与 Cookie 相对的一个解决方案是 Session,它是通过服务器来保持状态的。
当客户端访问服务器时,服务器根据需求设置 Session,将会话信息保存在服务器上,同时将标示 Session 的 SessionId 传递给客户端浏览器,浏览器将这个 SessionId 保存在内存中,我们称之为无过期时间的 Cookie。浏览器关闭后,这个 Cookie 就会被清掉,它不会存在于用户的 Cookie 临时文件。
以后浏览器每次请求都会额外加上这个参数值,服务器会根据这个 SessionId,就能取得客户端的数据信息。
Token
其实 Token 更多是在用户授权中使用,例如移动 App 通常采用 Token 进行验证。
Token 和 Session 有第一定的类似,但是服务器不保存状态,而是生成一个 Token 保存在客户端,这个 Token 是加密并确保完整性和不变性的,也就是修改后无效的,所以是安全的,可以保存在客户端。
同时 Token 支持跨域访问、无状态等,也能解决 Cookie 劫持(CSRF)的安全问题。
结束语
这里面主要讲述 HTTP 协议相关的一些基本原理和概念。其实每一个点,都是仍然需要深入理解的。HTTP 相关的内容实在很多,最好的方式是结合实践,平时多关注和思考,来加深相关的理解吧。