http

http到底是什么?

  • 定义
    它是一种网络传输协议,位于TCP/IP协议族的最顶层应用层。

  • HTTP
    Hypertext Transfer Protocol(超文本传输协议)和 HTML (Hypertext Markup Language 超文本标记语言) 一起诞生,用于在网络上请求和传输 HTML 内容。

    http工作模型

  • 浏览器

  1. 用户在浏览器输入地址回车访问
  2. 浏览器拼装请求报文发送给服务器
  3. 服务器接受处理请求发送响应报文给浏览器
  4. 浏览器解析响应报文并使用渲染引擎显示
  • 手机APP
  1. 用户触发一个网络请求
  2. 应用拼装HTTP报文请求发送给服务器
  3. 服务器接受报文请求解析处理返回响应报文
  4. 应用解析响应报文获取响应数据显示到手机界面

请求报文格式

示例

https://jack.com/users/?gender=male

  • https 协议类型
  • jack.com 服务器地址
  • users/?gender=male 路径path

如图报文请求格式

image

  • 请求行:Method(GET POST PUT DELETE…)、Path、HTTP version
  • Headers:请求的meta data,Meta Data就是元数据也就是数据中的数据。
  • Body:要发送给服务器的内容,这个Body只有当时Post等类型请求情况下才会有body。

Request请求Method类型

  • GET
    幂等一次操作和多次操作的结果是一样的
    取资源、对服务器数据不修改、不发送body

    1
    2
    GET /users/1 HTTP/1.1
    Host: api.github.com
  • POST
    主要用于增加或者修改资源、发送给服务器的内容写在body里面

    1
    2
    3
    4
    5
    POST /users HTTP/1.1
    Host: api.github.com
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 13
    name=jack&gender=male
  • PUT
    主要用于修改资源、发送给服务器内容写在body里面

1
2
3
4
5
PUT /users/1 HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
gender=female
  • DELETE
    幂等,一次和多次删除都是一样的。
    主要用于删除资源、不发送 Body
1
2
DELETE /users/1 HTTP/1.1
Host: api.github.com
  • HEAD

幂等

和 GET 使用方法完全相同唯一区别在于,返回的响应中没有 Body
可以用于做一些获取信息的操作比如断点续传,先head一下获取信息来判断是否需要做下一次请求;

Status Code

  • 1xx:临时性消息。如:100 (继续发送)、101(正在切换协议)
  • 2xx:成功。最典型的是 200(OK)、201(创建成功)。
  • 3xx:重定向。如 301(永久移动)、302(暂时移动)、304(内容未改变)。
  • 4xx:客户端错误。如 400(客户端请求错误)、401(认证失败)、403(被禁⽌止)、404(找不不到内容)。
  • 5xx:服务器器错误。如 500(服务器器内部错误)
  • Headers
    http消息的元数据(matedata数据的数据)
  • Host
    目标主机,不是在网络上用于寻址的,而是在目标服务器上用于定位子服务器的。
  1. 在报文拼装发送之前通过DNS寻址找到目标服务器
  2. 把host拼装在报文里面找到目标服务器

这种方式主要是用来处理一个服务器可能会有多个虚拟服务器,如果通过host可以精确的定位需要访问的服务器。

  • Content-Type/Content-Length
    body的类型和长度这个在Http中还是比较重要,因为客户端和服务器在进行数据传输的时候经常要约定一些数据格式的类型,不同Content-Type对应的报文拼装方式也是不一样的

text/html
请求 Web 页面返回响应的类型,Body 中返回 html 文本,这种type是最早的content-Type类型,早期互联网刚开始发展的时候就是通过html来传输渲染的。

响应报文

1
2
3
4
5
6
7
8
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 853
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
..............................

x-www-form-urlencoded
Web 页面纯文本表单的提交方式,如果是存文本的话可以使用这种encoded。

请求报文格式

1
2
3
4
5
POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
name=rengwuxian&gender=male

multitype/form-data

Web 页面含有二进制文件时的提交方式,推荐使用带文件的表单也可以上传文本的表单但是会比较消耗带宽。

请求报文格式

1
2
3
4
5
6
7
8
9
10
11
12
POST /users HTTP/1.1
Host: hencoder.com
Content-Type: multipart/form-data;boundary=
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 2382
>------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"
jack
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="avatar"; filename="avatar.jpg"
Content-Type: image/jpeg
JFIFHHvOwX9jximQrWa......

—-WebKitFormBoundary7MA4YWxkTrZu0gW就是一个数据的分界线,每个body都是以这个标识来分隔

application/json , image/jpeg , application/zip …
单项内容(文本或非文本都可以),用于 Web Api 的响应或者 POST / PUT 的请求,优点就是格式灵活格式自由。如果非要说缺点的话json可能在传输数据量上面会有点冗余,因为它有很多标点符号如果传输数据量大的话,这块会影响带宽的消耗。

其实早期很多应用在传输文本数据类型的时候,但是习惯于用前面几种方式,像JSON这种传输方式是在移动应用出来以后才开始流行起来的,但是在HTTP请求和响应的数据格式定制上还是比较少用,比如提交表单可能都习惯于用multitype/form-data来进行,但是从使用的简易度上来说,JSON是一个比较好的选择,没有流行起来可能是因为大前端是岁数比较小,我们后端小哥不习惯吧。

请求报文格式

1
2
3
4
5
6
7
8
POST /users HTTP/1.1
Host: hencoder.com
Content-Type: application/json; charset=utf-8
Content-Length: 38
{"name":"jack","gender":"male"}
Location
User-Agent
Range/Accpet-Range

  • Transfer: chunked (分块传输编码 Chunked Transfer Encoding)
    这种情况一般用于服务器暂时无法返回全部的信息,但是也不能让客户端一直等着所以可以分段传输一些资源给客户端。
1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1 200 OK
Content-Type:text/html
Transfer-Encoding:chunked

4
chun
9
ked trans
12
fer encoding
0

这个地方有4 9 12 0,读到0就是结尾其他的就是数据的长度,比如第一个是4那么开始读4个字符结果就是chun,在读9个 ked trans。这种方式可以对应的场景就是那些服务器可能需要处理时间比较久的逻辑,比如10秒钟,这个时候客户端总不能等着吧,那么就可以先返回一些数据给客户端先去展示。

  • Location
    指定重定向的⽬目标 URL,比如访问一个http://xxx.com 如果这个网站支持的是https://xxx.com,那么这个location值就是带Https的这站点,浏览器自动就做了一个这样的定向转发。
  • User-Agent
    用户代理理,即是谁实际发送请求、接受响应的,例例如手机浏览器器、某款手机 App。这个参数的来源是为了支持早期的火狐浏览器,由于之前有很多浏览器没有统一兼容性导致很多网站,只能在某一部分的浏览器达到很好的效果。很多网站需要做很多浏览器的适配,后面网站只去做火狐浏览器的兼容,所以这个User-Agent就全部写成了Mozilla,一直到现在一来都是大部分都是Mozilla这值。

这个值还可以用于手机端的适配,我们访问同一个网站在手机端和浏览器可能访问的效果都是不一样的,手机上显示的页面可能会不一样,这种都可以通过这个代理类型来区别如何进行适配。

  • Range / Accept-Range
    指定Body的内容范围,一般用于分段取内容。
  • REST
    网络上众说纷纷,个人觉得就是一种架构风格,一种规范设计最早是从HTTP开始。

  • Server-Client architecture
    C/S架构我给你发一个请求,你给我返回一个请求HTTP本身就是符合这种架构设计的。

  • StateLessness
    无状态就是前后之前没有任何关联,比如要获取一个用户信息但是没有登录,服务器肯定会告知客户端请先登录,http本身就是符合这种设计的。
  • Cacheability
    可缓存,http本身就是可以缓存的不管是机器还是节点,整个架构都是符合这个规范,和软件本身是没什么关系的。
  • Layered System
    系统分层意思就是客户端不管访问的是一个机器,还是一个集群,总之要保证我的访问是没问题的。这个规范HTTP也是必然的,不然达到这个要求那么软件也就是没法做了。
  • Code on demand
    服务器在返回的信息里面,可以返回一些可以执行代码的。比如javascript,打开一些网页里面会有一些可以执行的代码。

  • RESTful HTTP
    就是正确的使用HTTP,比如规定用GET就是用GET,用POST就用POST。

加密

  • 古代密码棒
    image
    古代最早的密码学就是这样的,为了防止信息的泄露这里有二个东西,不同规格的木棒(密钥),布带(密文)。通过这二个东西就是实现信息的加密了,只有在指定规格的木棒上面缠布带才能得到对应的信息。

替换式密码

最简单就体现就是在原始字符上面对每个字母进行+1,加完之后的字符就是密文了。

1
2
3
原始字符:ABCDEFFEJ  (对每个字符进行+1)
加密后字符:BCDEFGGFO
解密原始字符:ABCDEFFEJ (对每个字符进行-1)

解密在通过在密文上对每个字符进行一次-1得到就是我们的原文

现代加密

现代的加密方式由于有了计算机所以它支持复杂度更大,运算量更大的加密逻辑,但是它和核心原理其实也是和这种加密棒的原理很像。

  • 对称加密
    比木棒更加复杂的加密算法,通信双方使用同一个密钥。

  1. DES
    56位密钥,密钥太短被弃用了,因为有可能被穷举法破解就是我们说的暴力破解,就是一个一个的试。

  2. AES
    128位,192位,256位,主流的加密。
    被暴力破解的可能性很低,时间太久。

  3. 缺点
    密钥不能安全的在网络上传输,如果泄露加密的信息就会被破解。

关于破解
任何一种加密其实都没有被破解不了的一说,只是被破解的几率太小太小,比如我们如果通过穷举法去破解,它花上的时间可能要上千年这种时间点就不现实了。

为什么需要非对称加密,如果你的密钥需要在网络上传输,如何把密钥要安全的给到,这个安全传输本身就是一个难题。非对称加密可以解决这个问题,因为它是把公钥公开出来的,密钥只能自己持有。传输公开的都是公钥这样就解决了公钥需要传输的加密场景,非对称加密更加复杂它的加密原理和进制数据的溢出有关。

  • 非对称加密
  1. RSA

A通过B的公钥来加密原文,发送给B B得到密文之后使用自己的私钥进行一次解密,这样就可以得到原文。非对称加密中加密的密钥叫做公钥,解密密钥的叫做私钥,公钥是可以公开的谁需要发送信息给我都可以拿到此密钥进行加密发送,但是私钥是绝对不可以公开的只有是自己持有。