第二章 基础篇

08 | 键入网址再按下回车,后面究竟发生了什么?

2022-03-30-6tAjjv

09 | HTTP 报文是什么样子的?

2022-03-30-U4mROK

请求行

2022-03-30-sZzuN0

GET / HTTP/1.1

状态行

2022-03-30-KYdlwW

HTTP/1.1 200 OK

头部字段

2022-03-30-JH44ZA

使用头字段需要注意下面几点:

  • 字段名不区分大小写,例如“Host”也可以写成“host”,但首字母大写的可读性更好;
  • 字段名里不允许出现空格,可以使用连字符“-”,但不能使用下划线“_”。例如,“test-name”是合法的字段名,而“test name”“test_name”是不正确的字段名;
  • 字段名后面必须紧接着“:”,不能有空格,而“:”后的字段值前可以有多个空格;
  • 字段的顺序是没有意义的,可以任意排列不影响语义;
  • 字段原则上不能重复,除非这个字段本身的语义允许,例如 Set-Cookie。

常用头字段

  1. Host,请求字段,HTTP/1.1 规范里要求必须出现的字段。
  2. User-Agent,是请求字段,只出现在请求头里。它使用一个字符串来描述发起 HTTP 请求的客户端,服务器可以依据它来返回最合适此浏览器显示的页面。
  3. Date 字段是一个通用字段,但通常出现在响应头里,表示 HTTP 报文创建的时间,客户端可以使用这个时间再搭配其他字段决定缓存策略。
  4. Server 字段是响应字段,只能出现在响应头里。它告诉客户端当前正在提供 Web 服务的软件名称和版本号,例如在我们的实验环境里它就是“Server: openresty/1.15.8.1”,即使用的是 OpenResty 1.15.8.1。
  5. 实体字段里要说的一个是 Content-Length,它表示报文里 body 的长度,也就是请求头或响应头空行后面数据的长度。服务器看到这个字段,就知道了后续有多少数据,可以直接接收。如果没有这个字段,那么 body 就是不定长的,需要使用 chunked 方式分段传输。

10 | 应该如何理解请求方法?

标准请求方法

  1. GET:获取资源,可以理解为读取或者下载数据;
  2. HEAD:获取资源的元信息;
  3. POST:向资源提交数据,相当于写入或上传数据;
  4. PUT:类似 POST;
  5. DELETE:删除资源;
  6. CONNECT:建立特殊的连接隧道;
  7. OPTIONS:列出可对资源实行的方法;
  8. TRACE:追踪请求 - 响应的传输路径。

自定义方法

虽然 HTTP/1.1 里规定了八种请求方法,但它并没有限制我们只能用这八种方法,这也体现了 HTTP 协议良好的扩展性,我们可以任意添加请求动作,只要请求方和响应方都能理解就行。

安全

在 HTTP 协议里,所谓的“安全”是指请求方法不会“破坏”服务器上的资源,即不会对服务器上的资源造成实质的修改。

幂等

所谓的“幂等”实际上是一个数学用语,被借用到了 HTTP 协议里,意思是多次执行相同的操作,结果也和第一次是相同的,即多次“幂”后结果“相等”。

11 | 你能写出正确的网址吗?

2022-03-30-stBKlG

协议名://用户名:密码 @主机:端口/路径?查询参数#片段标识符

这里我也要再次提醒你注意,URI 的 path 部分必须以“/”开始,也就是必须包含“/”,不要把“/”误认为属于前面 authority。

这实际上是 file 类型 URI 的“特例”,它允许省略主机名,默认是本机 localhost。

URI 的编码

所以,URI 引入了编码机制,对于 ASCII 码以外的字符集和特殊字符做一个特殊的操作,把它们转换成与 URI 语义不冲突的形式。这在 RFC 规范里称为“escape”和“unescape”,俗称“转义”。

URI 转义的规则有点“简单粗暴”,直接把非 ASCII 码或特殊字符转换成十六进制字节值,然后前面再加上一个“%”。

12 | 响应状态码该怎么用?

响应码和请求方法一样是可以协商定义的。

1XX

1××类状态码属于提示信息,

  1. “101 Switching Protocols”。同意改变通讯协议。

2××

2××类状态码表示服务器收到并成功处理了客户端的请求,这也是客户端最愿意看到的状态码。

  1. “200 OK”。是最常见的成功状态码,表示一切正常。
  2. “204 No Content” 。表示一切正常,但响应头后没有 body 数据。
  3. “206 Partial Content”。表示一切正常,但 body 里的数据不是资源的全部,而是其中的一部分。

3××

3××类状态码表示客户端请求的资源发生了变动

  1. “301 Moved Permanently”。永久重定向。
  2. “302 Found”。临时重定向。
  3. “304 Not Modified”。缓存重定向。

4××

4××类状态码表示客户端发送的请求报文有误,服务器无法处理,它就是真正的“错误码”含义了。

400 Bad Request:是一个通用的错误码。

403 Forbidden:实际上不是客户端的请求出错,而是表示服务器禁止访问资源。

404 Not Found:资源在本服务器上未找到,所以无法提供给客户端。

405 Method Not Allowed:不允许使用某些方法操作资源,例如不允许 POST 只能 GET;

406 Not Acceptable:资源无法满足客户端请求的条件,例如请求中文但只有英文;

408 Request Timeout:请求超时,服务器等待了过长的时间;

409 Conflict:多个请求发生了冲突,可以理解为多线程并发时的竞态;

413 Request Entity Too Large:请求报文里的 body 太大;

414 Request-URI Too Long:请求行里的 URI 太大;

429 Too Many Requests:客户端发送了太多的请求,通常是由于服务器的限连策略;

431 Request Header Fields Too Large:请求头某个字段或总体太大;

5××

5××类状态码表示客户端请求报文正确,但服务器在处理时内部发生了错误,无法返回应有的响应数据,是服务器端的“错误码”。

500 Internal Server Error:与 400 类似,也是一个通用的错误码,服务器究竟发生了什么错误我们是不知道的。

501 Not Implemented:表示客户端请求的功能还不支持。

502 Bad Gateway:通常是服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误,但具体的错误原因也是不知道的。

503 Service Unavailable:表示服务器当前很忙,暂时无法响应服务,我们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503。

13 | HTTP 有哪些特点?

  • HTTP 是灵活可扩展的,可以任意添加头字段实现任意功能;

  • TTP 是可靠传输协议,基于 TCP/IP 协议“尽量”保证数据的送达;

  • HTTP 是应用层协议,比 FTP、SSH 等更通用功能更多,能够传输任意数据;

  • HTTP 使用了请求 - 应答模式,客户端主动发起请求,服务器被动回复请求;

  • HTTP 本质上是无状态的,每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。

14 | HTTP 有哪些优点?又有哪些缺点?

  • HTTP 最大的优点是简单、灵活和易于扩展;

  • HTTP 拥有成熟的软硬件环境,应用的非常广泛,是互联网的基础设施;

  • HTTP 是无状态的,可以轻松实现集群化,扩展性能,但有时也需要用 Cookie 技术来实现“有状态”;

  • HTTP 是明文传输,数据完全肉眼可见,能够方便地研究分析,但也容易被窃听;

  • HTTP 是不安全的,无法验证通信双方的身份,也不能判断报文是否被窜改;

  • HTTP 的性能不算差,但不完全适应现在的互联网,还有很大的提升空间。