HTTPS 的 SSL 加密实在传输层实现的
HTTP:超文本传输协议,是互联网上应用最广泛的一种网络协议,是客户端和服务端请求和相应的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的传输协议,HTTP 协议可以使浏览器更加高效,网络传输减少
HTTPS:以安全为目标的 HTTP 通道,简单讲就是 HTTP 的安全版,即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL
HTTPS 协议的主要作用:建立一个信息安全通道,来确保数据的传输,确保完善的的真实性
HTTP 传输的都是明文数据,也就是说没有加密的数据,网景公司设置了 SSL 协议来对 HTTP 协议传输的数据进行加密处理,简单来说 HTTPS 协议是由 HTTP 和 ssl 协议构建的可进行加密传输和身份认证的网络协议,比 HTTP 协议的安全性更高
HTTP 和 HTTPS 的主要区别:
对应的请求步骤:
Client 发起一个 HTTPS请求(例如HTTPS://blog.plumbiu.club
),根据 RFC2818 的规定,Client 知道需要连接 Server 的 443(默认)端口
Server 把事先配置好的公钥证书(public key certificate)返回给客户端
Client 验证公钥证书:比如是否在有效期内,证书的用途是不是匹配 Client 请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的 Root 证书或者Client 内置的 Root 证书)。如果验证通过则继续,不通过则显示警告信息
Client 使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给 Server
Server 使用自己的私钥(private key)解密这个消息,得到对称密钥。至此,Client 和 Server 双方都持有了相同的对称密钥
Server 使用对称密钥加密“明文内容A”,发送给 Client
Client 使用对称密钥解密响应的密文,得到“明文内容A”
Client 再次发起 HTTPS 的请求,使用对称密钥加密请求的“明文内容B”,然后 Server 使用对称密钥解密密文,得到“明文内容 B”
优点:
缺点:
一句话概括:
客户端和服务端都需要直到各自可收发,因此需要三次握手
简化逻辑图:
客户端将 TCP 报文标志位 SYN 置为 1,随机产生一个序号值 seq = J,保存在 TCP 首部的序列号(Sequence Number) 字段里,指名客户端打算连接的服务器端口,并将该数据包发送给服务器端,发送完毕后,客户端进入 SYN_SENT
状态,等待服务端确认
服务端收到的数据包后由标志位 SYN = 1 知道客户端请求建立连接,服务器端将 TCP 报文标志位 SYN 和 ACK 都置为 1, ack = J + 1,随机产生一个序列值 seq = K,并将该数据包发送给客户端已确认连接请求,服务端进入 SYN_RCVD
状态
客户端收到确认后,检查 ack 是否为 J+1,ACK 是否为 1,如果正确则将标志位 ACK 置为1,ack= K + 1,并将该数据包发送给服务器端,服务器端检查 ack 是否为 K + 1,ACK 是否为 1,如果正确则连接建立成功,客户端和服务器端进入 ESTABLISHED
状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
小写的 ack 和大写的 ACK 是不同的概念
- ack:Acknowledge number,表示头部确认号,是对上一个包的序号进行确认,即 ack = seq + 1
- ACK:TCP 首部的标志位,用于标志的 TCP 包是否对上一个包进行了确认操作,如果确认了,则把 ACK 标志位设置成 1
逻辑图:
在断开连接之前客户端和服务器都处于ESTABLISHED状态,双方都可以主动断开连接,以客户端主动断开连接为优。
第一次挥手:客户端打算断开连接,向服务器发送 FIN 报文(FIN 标记位被设置为 1,1 表示为 FIN,0 表示不是),FIN 报文中会指定一个序列号,之后客户端进入FIN_WAIT_1 状态。也就是客户端发出连接释放报文段(FIN报文),指定序列号 seq = u,主动关闭 TCP 连接,等待服务器的确认。
**第二次挥手:服务器收到连接释放报文段(FIN 报文)后,就向客户端发送 ACK 应答报文,以客户端的 FIN 报文的序列号 seq+1 作为ACK应答报文段的确认序列号 ack = seq+1 = u + 1。接着服务器进入CLOSE_WAIT(等待关闭)**状态,此时的 TCP 处于半关闭状态,客户端到服务器的连接释放。客户端收到来自服务器的 ACK 应答报文段后,进入 FIN_WAIT_2 状态。
第三次握手:服务器也打算断开连接,向客户端发送连接释放(FIN)报文段,之后服务器进入 LASK_ACK(最后确认)状态,等待客户端的确认。服务器的连接释放(FIN)报文段的FIN=1,ACK=1,序列号seq=m,确认序列号ack=u+1。
第四次握手:客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个ACK应答报文段,以连接释放(FIN)报文段的确认序号 ack 作为ACK应答报文段的序列号 seq,以连接释放(FIN)报文段的序列号 seq+1作为确认序号ack。之后客户端进入TIME_WAIT(时间等待)状态,服务器收到ACK应答报文段后,服务器就进入CLOSE(关闭)状态,到此服务器的连接已经完成关闭。客户端处于TIME_WAIT状态时,此时的TCP还未释放掉,需要等待2MSL后,客户端才进入CLOSE状态。
总结:
- 客户端打算关闭连接,向服务器发送报文,等待服务器确认
- 服务器接受到来自客户端的报文段,向客户端发送应答报文,等待服务器的数据发送完毕
- 服务器数据发送完毕,也准备断开,向客户端发送关闭连接的字段
- 客户端接受到来自服务器连接释放的报文,向服务器发送一个应答报文段,服务器收到后连接完成关闭,客户端等待 2MSL 后关闭
三次握手和四次挥手更加通俗的理解:
HTTP1.0
HTTP1.0 使用的是非持久连接,缺点是客户端必须为一个待请求的对象建立并维护一个新的连接,即每请求一个文档就要有两倍的 RTT 开销。并且由于同一个页面可能存在多个对象,所以非持久连接可能使一个页面的下载变得十分缓慢,这种短连接增加了网络传输的负担
RTT(Round Trip Time)
:一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值;
HTTP1.1
HTTP1.1 传输的内容是明文,不够安全
HTTP2.0
BOM 是浏览器对象,有着很多关于浏览器的属性
location 对象 | 作用 |
---|---|
loction.href | 返回或设置当前文档 URL |
location.search | 返回 URL 中查询字符串的部分(即 ? 之后的字符串) |
location.hash | 返回 URL 中的哈希地址(即 # 后面的字符串) |
location.host | 返回 URL 中的域名部分,例如 plumbiu.club |
location.hostname | 返回 URL 域名后面的部分,例如 https://blog.plumbiu.club/links 返回 /links |
location.port | 返回 URL 中的端口部分,例如 https://www.plumbiu.club:8001 返回 8001 |
location.protocol | 返回 URL 中的协议部分,即 // 之前的部分,例如 https://www.plumbiu.club 返回 https: |
location.assign(url: string) | 设置当前文档的 URL |
location.replace(url: string) | 也是设置当前文档的 URL,但是会在 history 对象的地址列表中移除这个 URL,即不能回退 |
location.reload() | 重载当前页面 |
history 对象 | 作用 |
---|---|
history.go(n: number) | 前进 n 个页数,n 可以是负数,也可以是正数 |
history.back() | 后退一页 |
history.forward() | 前进一页 |
Navigator 对象 | 作用 |
---|---|
navigator.userAgent | 返回用户代理头的字符串表示 |
navigator.cookieEnabled | 返回浏览器是否支持(启用) cookie |
iframe 元素会创建包含另一个文档的内联框架
缺点:
Doctype 声明于文档最前面,告诉浏览器以哪种规范来渲染页面,例如 html 或者 xhtml 规范
DOCTYPE(document type)
必须放在 html 文件最前面,它不是 HTML 标签,也没有结束标签
<!DOCTYPE html>
Cookie:由于 HTTP 是一个无状态协议,Cookie 出现的最大作用就是存储 sessionId 用来标识唯一用户
相同点:
Cookie
、sessionStorage
、localStorage
都是保存在浏览器端,用于临时存储客户端会话信息或者数据的方法,且是同源的不同点:
XSS(跨站脚本攻击),是指攻击者在返回的 HTML 中嵌入 JavaScript 脚本
在 HTTP 头部上配置 set-cookie
响应头,其中两个属性可以防止 XSS 攻击:
http-only
:防止 XSS,因为它会禁止 JavaScript 脚本来访问 cookiesecure
:告诉浏览器仅在请求为 https 是才会发送 cookie苹果的
safari
浏览器,为了把 PC 端大屏幕的页面更好的显示在小屏幕手机端,采用了双击缩放(doubel tap to zoom)方案,为了检测用户是单击操作还是双击操作而设置了 300ms 延迟
解决方案:
既然缩放是导致延迟的原因,那么我们可以禁止缩放
<meta name="viewport" content="width=device-width,user-scale=no"
FastClick 的原理是:检测到 touchend 时间后,like发出模拟 click 事件,并且把 浏览器 300ms 之后真正触发的事件阻断掉
npm i fastclick
document.addEventListener('DOMContentLoaded', () => {
FastClick.attach(document.body)
}, false)
HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599):
分类 | 分类描述 |
---|---|
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
HTTP状态码列表:
状态码 | 状态码英文名称 | 中文描述 |
---|---|---|
100 | Continue | 继续。客户端应继续其请求 |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
200 | OK | 请求成功。一般用于GET与POST请求 |
201 | Created | 已创建。成功请求并创建了新的资源 |
202 | Accepted | 已接受。已经接受请求,但未处理完成 |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
306 | Unused | 已经被废弃的HTTP状态码 |
307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
401 | Unauthorized | 请求要求用户的身份认证 |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
409 | Conflict | 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突 |
410 | Gone | 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
412 | Precondition Failed | 客户端请求信息的先决条件错误 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
416 | Requested range not satisfiable | 客户端请求的范围无效 |
417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
应答头 | 说明 |
---|---|
Allow | 服务器支持哪些请求方法(如GET、POST等)。 |
Content-Encoding | 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。 |
Content-Length | 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。 |
Content-Type | 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。 |
Date | 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。 |
Expires | 应该在什么时候认为文档已经过期,从而不再缓存它? |
Last-Modified | 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。 |
Location | 表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。 |
Refresh | 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。 注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。 注意Refresh的意义是"N秒之后刷新本页面或访问指定页面",而不是"每隔N秒刷新本页面或访问指定页面"。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV="Refresh" ...>。 注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。 |
Server | 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。 |
Set-Cookie | 设置和页面关联的Cookie。Servlet不应使用response.setHeader("Set-Cookie", ...),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。 |
WWW-Authenticate | 客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。 注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问(例如.htaccess)。 |
浏览器缓存分为强缓存和协商缓存,根据响应头内容(Cache-Control)来决定.
Cache-Control 取值:
属性值 | 作用 |
---|---|
public | 客户端和服务器都可以缓存资源 |
privite | 只有客户端可以缓存资源 |
no-cache | 客户端缓存资源,但是是否缓存需要经过协商缓存来验证 |
no-store | 不使用缓存 |
max-age | 缓存有效期 |
协商缓存
协商缓存的触发条件:
协商缓存的标识
Last-Modified
:文件在服务器最后被修改的事件,从服务器的 Response Headers 上获取
稍微总结一下:
expires
、cache-control
。如果 cache-control
和 expires
同时存在,cache-control
的优先级比 expires
高Last-Modified/If-Modified-Since
、Etag/If-None-Match
长话短说:
注:无缓存版本
更详细:
图片解释: