httpBasic

HTTP

请求报文的构成

1
2
3
4
5
6
7
(GET/POST..) (/index) HTTP/1.1  
协议 资源地址 http版本
(HOST: tzwlink.xyz)
域名

(userName=gre&age=21)
请求内容

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
GET /blogart HTTP/1.1  
HOST: tzwlink.xyz
Connection: keep-alive

name=great&age=21
```

## 响应报文的构成

```javascript
(HTTP/1.1) (200) (OK)
http版本 状态码 状态码解释原因
(Date: Tue, 10 Jul 2020 15:37:34 GMT)
创建响应的时间
(Content-Length: 600)
字节大小
(Content-Type: text/html)

(<html\>...)
响应内容

例如

HTTP/1.1 200 OK
Date: Tue, 10 Jul 2020 15:37:34 GMT
Content-Length: 600
Content-Type: text/html
<html\>....</html\>

HTTP的请求响应方法

GET

指定服务器并发送请求,一般返回文本内容

POST

向服务器发送数据,服务器返回处理结果

PUT

上传文本内容,类似 FTP 协议上传文件,但是不太安全,一般不使用

用来获取服务器的头部相关信息、资源更新时间等,服务器只返回头部信息,不返回主体内容

DELETE

用来请求服务器删除某项资源

OPTIONS

用来查询服务器支持哪些方法

OPTIONS \* HTTP/1.1  
HOST: tzwlink.xyz  

//响应  

HTTP/1.1 200 OK  
Allow: GET,POST,PUT,HEAD  

CONNECT

使用隧道连接,比如 SSL 安全套层

持久连接和Cookie

原始问题

原本的 http 中,一旦传输完成报文主体,那么 tcp 就断了,但是如果 html 文档里还有图片、数据也需要请求时,还要在建立 tcp 连接再次请求。这样的话太浪费,我们完全可以让 tcp 继续连接,把文档中需要请求的地方请求完,然后如果一段时间都没请求时在断开。

所以引入了 Content: keep-alive,要求就是只要任何一方不提出断开,那么就一直连接

管线化

以往,请求需要得到回应后才能继续下一条请求,这样其实一点也不高效。因为服务器端是可以同时处理大量请求的。

管线化技术实现了可以同时发送多个请求,然后依次响应,无需等待每一次的响应结束。这样一来 web 页面效率大大提高

以往的 http 传输完成后并不会保存信息,通过 Cookie 会在初次请求之后保存部分信息(比如用户登录信息),然后再次请求时可以将 Cookie 加入请求报文中

报文信息

报文格式

前面大概讲过

格式

例子

请求与响应

编码传输

某些时候文件内容较多可以采用编码压缩的方式,但是解压时会增大服务器负担

  • gzip
  • compress

分块传输

当文件较大时,可以分割为多个部分分时传送,让浏览器一块一块的显示页面

获取部分内容 “获取部分内容”)获取部分内容

当某个内容下载到一半失败时,重新下载往往从头开始,所以引入可以指定范围,比如重新加载时可以从后面一半开始。返回成功状态码 206

GET /great.png HTTP/1.1  
HOST: www.tzwlink.xyz  
Range: bytes = 5000\-10000  

//响应  

HTTP/1.1 200 OK  
Date: Tue, 10 Jul 2020 15:37:34 GMT  
Content-Range: bytes 5000\-10000/10000  
Content-Length: 5000  
Content-Type: image/jpeg

常见状态码

2XX

  • 200 表示成功处理请求,并且返回了响应报文内容
  • 204 表示成功处理请求,但是并没有什么资源可以返回,利用这个可以做一些数据修改,添加数据的请求
  • 206 表示成功处理部分内容的请求,返回请求所指定的报文内容

3XX

  • 301 永久重定向,将请求的 URI 资源永久重定向到某个指定资源位置
  • 302 临时重定向,可能重定向的资源还会再次改变
  • 303 上面两种状态码明文上规定重定向时不允许改变请求方法,但是实际使用时大家都不怎么遵守,所以增加 303 表示允许重定向时修改请求方法
  • 304 允许在特定条件下从缓存获取资源,因为如果重复的请求都要依靠服务端查询那么工作量太大,所以可以从缓存中获取,无需再从数据库查询

比如某个页面初次打开返回 200 OK ,因为第一次需要的数据需要服务端查询数据库生成,这时客服端会在缓存文件中保存 Last Modified;在相同的第二次请求发生时,客服端会在请求中加入 If Modified Since,服务端收到后会根据更新时间判断是该重新查询?返回 200,还是就让客服端用之前的缓存?返回 304

动态页面一般不会保存这些信息,所以不主动添加的话那么每次请求都是 200,如果要做缓存加速就需要添加 Last Modified

  • 307 禁止 POST 变成 GET

4XX

  • 400 请求报文出现语法错误,服务端无法解析请求,但是浏览器会像对待 200 那样对待这个状态码
  • 401 请求认证,在请求资源之前需要认证,需要包含 Authorization 请求证书信息,一般像远程连接数据库就会有这个
  • 403 拒绝请求,服务端可以无理由拒绝对指定资源的请求
  • 404 服务端找不到指定资源

5XX

  • 500 服务端内部程序出现 bug,运行错误
  • 503 服务端关闭服务维护了,请求超时

HTTPS

https-http-加密-认证-完整性保护 “https=http+加密+认证+完整性保护”)https=http+加密+认证+完整性保护

原始的http协议内容都是以明文发送,容易被盗取,并且通信时无法确认收到的信息是否完整,或者被篡改。也不知道通信双方是否真实;由此引入 https,事实上是在 http 上做了一些处理。

通过与 SSL 层合用,达到安全通信的效果。SSL 会先建立安全隧道才会通信的

  • 确认通信双方身份 : 通过证书认证*来确认双方身份的真实性
  • 加密处理 : 由发送方按照一定规则对 http 报文进行加密发送
  • 完整性验证 : 例如通过 MD5 和 SHA-1 散列值检验完整性

https 在 tcp 建立的基础上,还需要建立 SSL 连接,之后进行普通的经过加密的 http 请求

加密解密都需要秘钥,一般发送方使用对方提供的公共秘钥进行加密。接受方接受到了之后又使用自己的私有密钥进行解密

通信过程 “通信过程”)通信过程

  1. 客户端发送打招呼报文 client Hello给服务器,里面包含了 ssl 版本,加密组件等等信息,告诉服务端要干什么。
  2. 服务端收到了客户端打的招呼,就已 Server Hello 报文进行回复,告诉客服端服务器可以进行 ssl 通信。
  3. 紧接着服务端把自己的公开密钥证书发给客服端,客服端对发送的信息要依此进行加密,该报文叫做 Certificate 报文。
  4. 服务端还会在发一条报文 Server Hello Done,告诉客服端第一次握手(协商)结束,确认了需要用的密钥。
  5. 之后客服端作为回应发送 Client Key Exchange 报文,并且还发送了名为 Pre-master secret 的随机密码串。当然这条信息已经经过第三步的加密处理。
  6. 客户端又继续发送 Change Cipher Spec 报文,告诉服务端从这里开始以后我发送报文就要按照刚刚的 Pre-master secret 随机密码串进行加密。当然这之前还是按照第三步服务端给的密钥加密。
  7. 客服端最后发送 Finshed 报文表示结束。
  8. 服务端必须正确解析上一步客服端发送的 Finshed 报文,因为里面包含了从连接开始到这一步之前所有报文的整体校验值,如果服务端成功解析说明密钥交换成功,服务端就会发送 Change Cipher Spec 报文
  9. 最后服务端也发送 Finshed 报文表示整个 ssl 连接成功可以进行 http 加密通信了
  • 断开连接时客服端会发送 close_notify 报文表示断开。在这后 tcp 连接也断开。

图片来自图解HTTP

http通信示意图

Author: Greatiga
Link: http://example.com/computerNetwork/httpBasic/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.