

一面中，如果有笔试，考HTTP协议的可能性较大。

## 前言

一面要讲的内容：

- HTTP协议的主要特点

- HTTP报文的组成部分

- HTTP方法

- get 和 post的区别

- HTTP状态码

- 什么是持久连接

- 什么是管线化


二面要讲的内容；

- 缓存

- CSRF攻击


## HTTP协议的主要特点

- 简单快速

- 灵活

- **无连接**

- **无状态**


通常我们要答出以上四个内容。如果实在记不住，一定要记得后面的两个：**无连接、无状态**。


我们分别来解释一下。


### 简单快速

**简单**：每个资源（比如图片、页面）都通过 url 来定位。这都是固定的，在http协议中，处理起来也比较简单，想访问什么资源，直接输入url即可。


### 灵活

http协议的头部有一个`数据类型`，通过http协议，就可以完成不同数据类型的传输。

### 无连接

连接一次，就会断开，不会继续保持连接。

### 无状态

客户端和服务器端是两种身份。第一次请求结束后，就断开了，第二次请求时，**服务器端并没有记住之前的状态**，也就是说，服务器端无法区分客户端是否为同一个人、同一个身份。

有的时候，我们访问网站时，网站能记住我们的账号，这个是通过其他的手段（比如 session）做到的，并不是http协议能做到的。


## HTTP报文的组成部分

![](http://img.smyhvae.com/20180306_1400.png)

在回答此问题时，我们要按照顺序回答：

- 先回答的是，http报文包括：**请求报文**和**响应报文**。

- 再回答的是，每个报文包含什么部分。

- 最后回答，每个部分的内容是什么

### 请求报文包括：

![](http://img.smyhvae.com/20180228_1505.jpg)

- 请求行：包括请求方法、请求的url、http协议及版本。

- 请求头：一大堆的键值对。

- **空行**指的是：当服务器在解析请求头的时候，如果遇到了空行，则表明，后面的内容是请求体。

- 请求体：数据部分。

### 响应报文包括：

![](http://img.smyhvae.com/20180228_1510.jpg)


- 状态行：http协议及版本、状态码及状态描述。

- 响应头

- 空行

- 响应体


## HTTP方法

包括：

- GET：获取资源

- POST：传输资源

- put：更新资源

- DELETE：删除资源

- HEAD：获得报文首部

HTTP方法有很多，但是上面这五个方法，要求在面试时全部说出来，不要漏掉。

get 和 post 比较常见。

put 和 delete 在实际应用中用的很少。况且，业务中，一般不删除服务器端的资源。

head 可能偶尔用的到。


## get 和 post的区别

![](http://img.smyhvae.com/20180306_1415.png)

区别有很多，如果记不住，面试时，至少要任意答出其中的三四条。

有一点要强调，**get是相对不隐私的，而post是相对隐私的**。

我们大概要记住以下几点：

1、浏览器在回退时，get**不会重新请求**，但是post会重新请求。【重要】

2、get请求会被浏览器**主动缓存**，而post不会。【重要】

3、get请求的参数，会报**保留**在浏览器的**历史记录**里，而post不会。做业务时要注意。为了防止CSRF攻击，很多公司把get统一改成了post。

4、get请求在url中传递的参数有大小限制，基本是2kb，不同的浏览器略有不同。而post没有注意。

5、get的参数是直接暴露在url上的，相对不安全。而post是放在请求体中的。


## http状态码

http状态码分类：

![](http://img.smyhvae.com/20180306_1430.png)

常见的http状态码：

![](http://img.smyhvae.com/20180306_1431.png)


部分解释：

- 206的应用：`range`指的是请求的范围，客户端只请求某个大文件里的一部分内容。比如说，如果播放视频地址或音频地址的前面一部分，可以用到206。


- 301：重定向（永久）。

- 302：重定向（临时）。

- 304：我这个服务器告诉客户端，你已经有缓存了，不需要从我这里取了。


![](http://img.smyhvae.com/20180306_1440.png)

400和401用的不多。403指的是请求被拒绝。404指的是资源不存在。

## 持久链接/http长连接

> 如果你能答出持久链接，这是面试官很想知道的一个点。


- **轮询**：http1.0中，客户端每隔很短的时间，都会对服务器发出请求，查看是否有新的消息，只要轮询速度足够快，例如1秒，就能给人造成交互是实时进行的印象。这种做法是无奈之举，实际上对服务器、客户端双方都造成了大量的性能浪费。


- **长连接**：HTTP1.1中，通过使用Connection:keep-alive进行长连接，。客户端只请求一次，但是服务器会将继续保持连接，当再次请求时，避免了重新建立连接。

注意，HTTP 1.1默认进行持久连接。在一次 TCP 连接中可以完成多个 HTTP 请求，但是对**每个请求仍然要单独发 header**，Keep-Alive不会永久保持连接，它有一个保持时间，可以在不同的服务器软件（如Apache）中设定这个时间。


## 长连接中的管线化

> 如果能答出**管线化**，则属于加分项。

### 管线化的原理

长连接时，**默认**的请求这样的：

```
	请求1 --> 响应1 -->请求2 --> 响应2 --> 请求3 --> 响应3
```

长连接中的管线化，请求是这样的：

```
	请求1 --> 请求2 --> 请求3 --> 响应1 --> 响应2 --> 响应3
```


管线化就是，我把现在的请求打包，一次性发过去，你也给我一次响应回来。


### 管线化的注意事项


面试时，不会深究管线化。如果真要问你，就回答：“我没怎么研究过，准备回去看看~”

