08 | 键入网址再按下回车,后面究竟发生了什么?
简要叙述一下这次最简单的浏览器 HTTP 请求过程:
- 浏览器从地址栏的输入中获得服务器的 IP 地址和端口号;
- 浏览器用 TCP 的三次握手与服务器建立连接;
- 浏览器向服务器发送拼好的报文;
- 服务器收到报文后处理请求,同样拼好报文再发给浏览器;
- 浏览器解析报文,渲染输出页面。 还存在DNS解析,同时CDN会缓存网站的大部分资源,比如图片、CSS样式表。
09 | HTTP报文是什么样子的?
- 报文结构 HTTP 协议的请求报文和响应报文的结构基本相同,由三大部分组成:
- 起始行(start line):描述请求或响应的基本信息;
- 头部字段集合(header):使用 key-value 形式更详细地说明报文;
- 消息正文(entity):实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据。
- 请求行 请求行由三部分构成:
- 请求方法:是一个动词,如 GET/POST,表示对资源的操作;
- 请求目标:通常是一个 URI,标记了请求方法要操作的资源;
- 版本号:表示报文使用的 HTTP 协议版本。
- 状态行 同样也是由三部分构成:
- 版本号:表示报文使用的 HTTP 协议版本;
- 状态码:一个三位数,用代码的形式表示处理的结果,比如 200 是成功,500 是服务器错误;
- 原因:作为数字状态码补充,是更详细的解释文字,帮助人理解原因。
- 头部字段 HTTP 协议规定了非常多的头部字段,实现各种各样的功能,但基本上可以分为四大类:
-
通用字段:在请求头和响应头里都可以出现;
- Date
-
请求字段:仅能出现在请求头里,进一步说明请求信息或者额外的附加条件;
- Host
- User-Agent
-
响应字段:仅能出现在响应头里,补充说明响应报文的信息;
- Server
-
实体字段:它实际上属于通用字段,但专门描述 body 的额外信息。
- Content-Length。表示报文里body的长度。
10 | 应该如何理解请求方法?
- GET:获取资源,可以理解为读取或者下载数据;
- HEAD:获取资源的元信息;服务器不会返回请求的实体数据,只会传回响应头,也就是资源的“元信息”。HEAD 方法可以看做是 GET 方法的一个“简化版”。因为它的响应头与 GET 完全相同,所以可以用在很多并不真正需要资源的场合,避免传输 body 数据的浪费。
- POST:向资源提交数据,相当于写入或上传数据;POST 表示的是“新建”“create”的含义。
- PUT:类似 POST; 而PUT 是“修改”“update”的含义。
- DELETE:删除资源;
- CONNECT:建立特殊的连接隧道;要求服务器为客户端和另一台远程服务器建立一条特殊的连接隧道,这时 Web 服务器在中间充当了代理的角色。
- OPTIONS:列出可对资源实行的方法;在响应头的 Allow 字段里返回。
- TRACE:追踪请求-响应的传输路径。多用于对 HTTP 链路的测试或诊断。
安全与幂等
- 所谓的“安全”是指请求方法不会“破坏”服务器上的资源,即不会对服务器上的资源造成实质的修改。
- 所谓的“幂等”实际上是一个数学用语,被借用到了 HTTP 协议里,意思是多次执行相同的操作,结果也都是相同的,即多次“幂”后结果“相等”。
11 | 你能写出正确的网址吗?
- URI 的格式
- URI 的基本组成 URI 通常由 scheme、host:port、path 和 query 四个部分组成,有的可以省略;
- scheme 叫“方案名”或者“协议名”,表示资源应该使用哪种协议来访问;
- “host:port”表示资源所在的主机名和端口号;
- path 标记资源所在的位置;
- query 表示对资源附加的额外要求;
客户端和服务器看到的 URI 是不一样的。客户端看到的必须是完整的 URI,使用特定的协议去连接特定的主机,而服务器看到的只是报文请求行里被删除了协议名和主机名的 URI。
- URI的完整格式
第一个多出的部分是协议名之后、主机名之前的身份信息“user:passwd@”,表示登录主机时的用户名和密码,但现在已经不推荐使用这种形式了(RFC7230),因为它把敏感信息以明文形式暴露出来,存在严重的安全隐患。
第二个多出的部分是查询参数后的片段标识符“#fragment”,它是 URI 所定位的资源内部的一个“锚点”或者说是“标签”,浏览器可以在获取资源后直接跳转到它指示的位置。但片段标识符仅能由浏览器这样的客户端使用,服务器是看不到的。
- URI 的编码 URI 转义的规则有点“简单粗暴”,直接把非 ASCII 码或特殊字符转换成十六进制字节值,然后前面再加上一个“%”。
12 | 响应状态码该怎么用?
-
1××:提示信息,表示目前是协议处理的中间状态,还需要后续的操作;
- 101 ,它的意思是客户端使用 Upgrade 头字段,要求在 HTTP 协议的基础上改成其他的协议继续通信,比如 WebSocket。而如果服务器也同意变更协议,就会发送状态码 101,但这之后的数据传输就不会再使用 HTTP 了。
-
2××:成功,报文已经收到并被正确处理
- 200 OK,表示成功的请求。
- 204 No Content,响应头后没有body数据。
- 206 Partial Content,是 HTTP 分块下载或断点续传的基础,在客户端发送“范围请求”、要求获取资源的部分数据时出现,body里的数据不是资源的全部,而是其中的一部分。
-
3××:重定向,资源位置发生变动,需要客户端重新发送请求;
- 301 Moved Permanently,“永久重定向”,含义是此次请求的资源已经不存在了,需要改用新的 URI 再次访问。
- 302 Found,“临时重定向”,意思是请求的资源还在,但需要暂时用另一个 URI 来访问。
- 304 Not Modified,它用于 If-Modified-Since 等条件请求,表示资源未修改,用于缓存控制。
-
4××:客户端错误,请求报文有误,服务器无法处理;
- 400 Bad Request,请求报文有错误。
- 403 Forbidden,表示服务器禁止访问资源。
- 404 Not Found,访问的资源找不到。
-
5××:服务器错误,服务器在处理请求时内部发生了错误。
- 500 Internal Server Error,服务器出错。
- 501 Not Implemented,表示客户端请求的功能还不支持。
- 502 Bad Gateway,服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误。
- 503 Service Unavailable,表示服务器当前很忙,暂时无法响应服务。
13 | HTTP有哪些特点?
- 灵活可扩展,可以任意添加头字段实现任意功能。
- 可靠传输,基于TCP/IP协议。
- 应用层协议,能够传输任意数据。
- 请求-应答通信模式
- 无状态,每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。
14 | HTTP有哪些优点?又有哪些缺点?
-
简单、灵活、易于扩展
-
应用广泛、环境成熟
-
无状态
- 好处:不需要额外的资源来记录状态信息,实现简单,还能减轻服务器的负担。可以轻松实现集群化,扩展性能
- 坏处:服务器不知道请求是相互关联的。需要用 Cookie 技术来实现“有状态”;
-
明文
- 好处:很容易查看或者修改。
- 坏处: 资源信息容易暴露。
-
不安全 无法验证通信双方的身份,也不能判断报文是否被篡改;
-
性能