# HTTP 协议
特点:简单快速,灵活,无连接,无状态
无状态的意思是其数据包的发送、传输和接收都是相互独立的,无记忆的。无连接的意思是指通信双方都不长久的维持对方的任何信息。
# HTTP 协议报文组成
# 1. 请求报文组成
- 请求行:http 方法、页面 url 地址、协议/版本;
- 请求头:key-value;
- 空行:分隔符 CRLF;
- 请求体;
常用请求头与响应头
常用请求头:
- Accept:代表发送端(客户端)希望接受的数据类型,可以为一个或多个 MIME 类型的值
- Content-Type:代表发送端(客户端|服务器)发送的实体数据的数据类型 - application/x-www-form-urlencoded - application/json - multipart/form-data - text/xml
- Cookie:包含 sessionId
- Referer:表示这个请求是从哪个 URL 过来的
- Cache-Control:no-cache
- Connection:keep-alive
- Host:初始 URL 中的主机和端口
- User-Agent:浏览器类型
常用响应头:
- Cache-Control:max-age=3600
- ETag
- Location:
- Set-Cookie:服务端可以设置客户端的 Cookie
# 2. 响应报文组成
- 响应行:协议/版本、状态码;
- 响应头:key-value;
- 空行:分隔符 CRLF;
- 响应体;
# HTTP 方法
- GET:获取资源
- POST:传输资源
- PUT:更新资源
- DELETE:删除资源
- HEAD:获取报文首部(报文头)
# GET 与 POST 的区别(关注前 5 点)
- GET 在浏览器回退时是不会重复提交的,而 POST 会再次提交请求;
- GET 请求会被浏览器主动缓存,而 POST 不会,除非手动设置;
- GET 请求参数会被完整保留在浏览器历史记录中,而 POST 中的参数不会被保留;
- GET 参数通过 URL 传递,POST 放在 Request body 中;
- GET 请求在 URL 中传参是有长度限制的(一般为 2kb),而 POST 没有限制;
- get 会产生一个 tcp 数据包,而 post 产生两个,先发 headers 响应 100 continue,再发 data 响应 200;
- GET 产生的 URL 地址可以被收藏,而 POST 不可以;
- GET 参数直接放在 URL 中,不能传递敏感信息;
- GET 只能进行 url 编码,而 POST 支持多种编码方式。
# HTTP 状态码及常用端口
# 状态码
- 1xx:指示信息
- 2xx:成功 - 200 OK:客户端请求成功
- 204 No content:表示请求成功,但响应报文不含实体的主体部分 - 206 Partial Content:客户端发送带 Range 头的 Get 请求,服务器会按照 Range 截取对应数据返回,通常用于 video 标签或 audio 标签请求一个大的视音频文件时,返回 range 部分
- 3xx:重定向 - 301 Moved Permanently:永久重定向,所请求的页面已经永久转移至新 url - 302 Found:临时性重定向,所请求的页面已经临时转移至新的 url - 303 和 307 是 HTTP1.1 新加的,它们是对 HTTP1.0 中的 302 状态码的细化 - 303,POST 重定向为 GET - 307,不会把 POST 转为 GET - 304 Not Modified:客户端存在缓存并且此缓存未被更改可继续使用
- 4xx:客户端错误 - 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
- 401 unauthorized:表示发送的请求缺少身份认证信息 - 403 Forbidden:对被请求页面的访问被禁止 - 404 Not Found:请求资源不存在
- 5xx:服务器错误 - 500 Internal Server Error:服务器错误 - 503 Server Unavailable:服务器不可用,临时过载宕机,导致请求未完成
# ajax302 重定向跨域问题
ajax 发起的接口请求 和 浏览器直接发起的页面访问请求 有一定区别:
- 浏览器可以通过返回的 http 状态进行相应的操作,如访问一个页面,此页面 3xx 重定向时,浏览器可以获取到重定向后的 url,然后把地址栏的 url 替换,完成重定向动作。
- ajax 的目的就是无刷新的,所以对于服务器端进行了 3xx 重定向时,ajax 会获取到重定向状态值 3xx 和重定向 url,然后再此发送一个新请求去请求重定向 url。
因此,如果这个后端接口重定向给的 url 是另外一个域名的地址,那么此时就会出现跨域问题。
解决方式是:ajax 在第一次得到相应处理后,主动通过js
做一次location.href跳转
。目的是让浏览器去请求重定向的接口而不是 ajax。
# 常用端口
- http 80
- https 443
- DNS 53
- FTP 20 21
- SMTP 25
- POP3 110
# 长连接(持久连接或连接重用)
# 概念
http1.1
版本才支持的传输模式;- HTTP 协议采用“请求-应答”模式,分为
普通模式
和keep-alive
模式这两种模式; - 当使用
普通模式
时,每个请求/应答,客户端和服务器都要新建一个连接,完成之后立即断开(HTTP协议为无连接的协议
)。 - 当使用
Keep-alive
模式时(又称持久连接或连接重用
),keep-alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,keep-alive 功能避免了重新建立连接
。 - 注意: keep-alive 不会永远保持,它有一个持续时间,一般在服务器中配置(如 apache),另外长连接需要客户端和服务器都支持时才有效。
# 从两个层面定义
# 先看 tcp/ip 层面的定义:
- 长连接:一个 tcp/ip 连接上可以连续发送多个数据包,在 tcp 连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持(类似于心跳包)
- 短连接:通信双方有数据交互时,就建立一个 tcp 连接,数据发送完成后,则断开此 tcp 连接
# 在 http 层面的定义:
http1.0中,默认使用的是短连接
,也就是说,浏览器每进行一次 http 操作,就建立一次连接,任务结束就中断连接,譬如每一个静态资源请求时都是一个单独的连接http1.1起,默认使用长连接
,使用长连接会有这一行Connection: keep-alive
,在长连接的情况下,当一个网页打开完成后,客户端和服务端之间用于传输 http 的 tcp 连接不会关闭,如果客户端再次访问这个服务器的页面,会继续使用这一条已经建立的连接
# 什么是管线化
- 持久连接时,某个连接上消息的传递类似于:
请求1-》响应1-》请求2-》响应2-》请求3-》响应3
; - 持久连接时,管线化是指某个连接上的消息传递类似于:
请求1-》请求2-》请求3-》响应1-》响应2-》响应3
(即打包一次发送多个请求,一次返回多个响应); - 管线化是在持久连接的情况下完成的,仅 http1.1 支持;
- 只有 GET 和 HEAD 请求可以进行管线化;
- 管线化不会影响响应到来的顺序;
- 很多代理程序对管线化支持并不好,因此 Chrome 和 FF 默认并未开启管线化支持。初次创建连接时不应启动管线机制,因为对方服务器可能不支持。
# HTTP 2.0
http2.0 不是 https,它相当于是 http 的下一代规范(譬如 https 的请求可以是 http2.0 规范的)。
# http2.0 与 http1.1 的显著不同点:
- http1.1 是一对一的:
一个tcp/ip请求只能请求一个资源
,由于 tcp/ip 本身有并发数限制,所以当资源一多,速度就显著慢下来; - http2.0 是一对多的:
一个tcp/ip请求可以请求多个资源
,也就是说,只要一次 tcp/ip 请求,就可以请求若干个资源,分割成更小的帧请求,速度明显提升。
所以,如果 http2.0 全面应用,很多 http1.1 中的优化方案就无需用到了(譬如打包成精灵图,静态资源多域名拆分等)。
# http2.0 特性
多路复用
(即一个 tcp/ip 连接可以请求多个资源);首部压缩
(http 头部压缩,减少体积);服务器端推送server push
(服务端可以对客户端的一个请求发出多个响应,可以主动通知客户端);二进制分帧
(在应用层跟传送层之间增加了一个二进制分帧层,改进传输性能,实现低延迟和高吞吐量);请求优先级
(如果流被赋予了优先级,它就会基于这个优先级来处理,由服务器决定需要多少资源来处理该请求)。
# https
- https 其实就是身披 SSL 协议这层外壳的 http。https 并非是应用层的一种新协议,只是 https 通信接口部分用 SSL(Secure Socket Layer) 和 TLS(Transport Layer Security)协议代替而已。因此 https 又叫
HTTP over SSL
, HTTP over TLS。 - https 是 http 的安全版本,譬如一些支付等操作基本都是基于 https 的,因为 http 请求的安全系数太低了;
- 简单来看,https 与 http 的区别就是:
在请求前,会建立ssl链接,确保接下来的通信都是加密的,无法被轻易截取分析
。 - 一般来说,如果要将网站升级成 https,需要后端支持(后端需要申请证书等),然后 https 的开销也比 http 要大(因为需要额外建立安全链接以及加密等),所以一般来说 http2.0 配合 https 的体验更佳(因为 http2.0 更快了)。
# https 是时代趋势
目前全球互联网正在从 HTTP 想 HTTPS 大迁移,Chrome 和火狐将对不采用 HTTPS 加密的网站提示不安全,苹果要求所有 APP 同学都必须采用 HTTPS 加密,小程序强制要求服务器端使用 HTTPS 请求。
# http 和 https 的区别
- https 协议需要到 CA (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。(原来网易官网是 http,而网易邮箱是 https。)
- http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
- http 的连接很简单,是无状态的。Https 协议是由 SSL+Http 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)
# CA 证书有哪些加密算法
非对称加密 | 对称加密 | 单向加密 |
---|---|---|
RSA(如 git)、ECC(数字货币) | DES、AES | MD5 |
非对称加密是客户端用来向服务端传对称密钥的 | 对称加密用来双方传数据 | 略 |
# 对称加密和不对称加密的区别
- 「对称加密」加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。
- 「非对称加密」使用了一对密钥(公钥与私钥),所以安全性高,但加密与解密速度慢。
# CA 证书在客户端还是在服务端
服务器端的 CA 证书包含了非对称加密的公钥和私钥,将只包含公钥的证书发送给客户端。
# HTTPS 采用对称加密+非对称加密的混合方式
- HTTPS 只在证书验证阶段使用
「非对称加密」
,在之后的内容传输阶段使用「对称加密」
。 - 那为什么一开始用不对称,后面用对称加密呢?这正是因为二者特点所决定的: - 非对称加密的加解密效率是非常低的(计算复杂度高,极端情况下 1000 倍),对于大量数据交互来说这是无法接受的。 - 对称加密使用同样的密钥,并需要将密钥在网络传输,不安全。
- 解决方式就是: - 客户端,https 将生成的随机数使用
「非对称加密」
的公钥进行加密,然后发送出去; - 服务端使用「非对称加密」
的私钥进行解密,得到对称加密的密钥,然后双方可以使用对称加密来进行信息传输。
# https 的请求流程
- 服务端发送公钥到 CA 认证中心,CA 会签发一个证书给服务端;
- 客户端发起 HTTPS 请求,服务端返回证书+公钥;
- 客户端首先会拿证书去 CA 进行验证;
- 验证通过后,本地生成用于改造对称加密算法的随机数;
- 再通过证书中的公钥(
「非对称加密」
)对随机数进行加密得到随机数密钥
(也就是对称密钥),传输到服务端; - 服务端接收后,通过私钥解密(
「非对称解密」
)得到随机数密钥
; - 之后的数据交互就可以通过
随机数密钥
(也就是对称密钥)执行「对称加密算法」
了。
# 扩展:SSH 验证过程
SSH 验证过程比 https 的请求过程要简单一些:
- 客户端通过某种方式,将公钥保存在服务端。
- 当客户端要登录服务器时,会发送验证请求;
- 服务器会用公钥加密一个随机数,传给客户端;
- 客户端会使用私钥解密得到结果传给服务端,服务端比对完成验证。