1 网络工作原理
1.1 网络模型
网络模型共有两种,OSI七层模型和TCP/IP四层模型
OSI七层模型 | TCP/IP四层模型 |
---|---|
application (应用层) | application (应用层) |
presentation (展示层) | |
session (会话层) | |
transport (传输层) | transport (传输层) |
network (网络层) | network (网络层) |
data link (数据链路层) | link (链路层) |
physical (物理层) |
1.2 传输层
- 传输层提供端到端的通信,即进程和进程之间的通信。(端口标识进程)
- 传输层需要对报文进行差错检测
- 提供TCP和UDP两种不同的传输协议
【端口】
端口号长度为16bit,范围0-65535,熟知端口号0-1023
FTP-21,TELNET-23,SMTP-25,DNS-53,HTTP-80,HTTPS-443
【套接字】IP:Port
ip地址和端口号唯一确定网络中的通信进程
1.2.1 UDP
user data protocol-无连接的非可靠传输协议,仅提供多路复用和对数据的错误检查两种服务。
主要用于对实时性有高要求的应用,包括DNS、TFTP、SNMP、RTP(实时传输协议)
UDP首部为固定的8B,包括源端口号、目的端口号、长度、校验和(校验和的计算请查看计网部分内容复习)
请注意,真实情况下UDP首部还会包括一个12B伪首部,所以udp数据报的真实结构:伪首部+首部+数据,这个伪首部实际上是ip数据报的首部
1.2.2 TCP
transmission control protocol-面向连接的可靠服务,不提供广播或者组播服务,包括确认、流量控制、拥塞管理等。
常见应用:FTP、HTTP、TELNET
TCP首部包含固定20B和可变部分
1.2.2.1 建立连接-三次握手
- 客户端发送带SYN标志的数据包,发送一个随机序列号
- 接收端/服务端收到后返回带有SYN和ACK标志的数据包,确认收到的序列号(ack=x+1)并发送自己的SYN包(seq=y)
- 客户端向服务端发送确认包,两者都进入established状态开始传输数据
1.2.2.2 释放连接-四次挥手
- 客户端发送带FIN标志的数据包以及当前传输数据序列号
- 服务端向客户端发送ACK确认数据包,并将剩余数据继续传输
- 服务端将所有数据传输完毕后,向客户端发送FIN和ACK数据包
- 客户端收到报文后发送确认数据报,服务端接收后进入closed状态,客户端在等待2*MSL(最长报文段寿命)后进入closed状态
客户端和服务端的任何一方都可以主动发起释放连接的请求
1.2.2.3 重传
超时和冗余ACK会触发TCP重传
- 超时:对每个发送报文段设置一个计时器,重传时间到期但是未收到确认就要自动重传。
- 冗余ACK:发送方收到了两次某个报文段的ACK,通常在比当前期望的序号大的报文到达时,再次发送前面已经接收到的报文序列ACK
1.2.2.4 流量控制
基于滑动窗口协议控制流量,确认报文携带允许传输的窗口大小,进行端到端的调整
1.2.2.5 拥塞控制
拥塞控制一共有4种算法:
- 慢开始:将发送方的拥塞窗口先置为1(一个最大报文段长度),收到确认后逐步增大拥塞窗口(加倍:1->2, 2->4)
在慢开始达到了规定阈值后,改用拥塞避免算法 - 拥塞避免:每经过一个往返时延RTT将拥塞窗口加1,出现拥塞时(未按时收到确认),将拥塞窗口重新设为1,重新执行慢开始算法(慢开始阈值改为一半?)
- 快重传:通过发送冗余ACK包的方式来触发重传
- 快恢复:把慢开始的阈值设为当前窗口大小的一半,然后使用拥塞避免算法将窗口缓慢增大(逐步加1)。【相当于跳过了窗口降为1的过程】
1.2.2.5 粘包问题
数据包头尾相连
1.2.2.6 客户端与服务端建立长连接的方式
websocket:一次握手建立连接,全双工通信,服务器可以主动发送信息
1.2.2.7 通过socket建立连接
2 HTTP/HTTPS
超文本传输协议,用于从服务器传输超文本内容给客户端浏览器
更加详细内容参考这篇博客
2.1 HTTP请求和响应步骤
- 客户端和服务端之间建立TCP连接
- 客户端发送http请求(POST方法需要带上请求体)
- 服务端接受请求并返回对应状态信息和数据
- 释放TCP连接,除非要求connection keep alive
- 浏览器解析并渲染
2.2 HTTP请求类型
方法 | 描述 |
---|---|
GET | 请求指定页面信息,返回实体 |
POST | 向指定资源提交数据处理请求,需要携带请求体 |
HEAD | 类似get请求,返回响应中没有具体内容,通常用于获取报头 |
DELETE | 请求服务器删除指定资源 |
PUT | 从客户端向服务器传送数据取代指定的内容 |
TRACE | 回显服务器收到请求,用于测试或者诊断 |
OPTIONS | 允许客户端查看服务器性能 |
CONNECT | 将连接改为管道方式的代理服务器 |
【GET和POST的区别】
- 浏览器回退表现不同:GET在浏览器回退时是无害的,而POST会再次提交请求(如表单等数据)
- 浏览器对请求地址的处理不同:GET请求地址会被浏览器主动缓存,而POST不会,除非手动设置
- 浏览器对响应的处理不同:GET请求参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留;GET请求获取的资源可以作为书签保存,POST不可以
- 参数大小不同:GET请求在URL中传送的参数是有长度的限制,而POST没有限制
- 安全性不同. GET参数通过URL传递,会暴露,不安全;POST放在Request Body中,相对更安全
- 针对数据操作的类型不同:GET对数据进行查询,POST主要对数据进行增删改!简单说,GET是只读,POST是写。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
2.3 HTTP报文
2.3.1 请求报文
- 请求行:方法+URL+HTTP协议版本
- 请求头:每一行:一个头部字段名+值
- 空行
- 请求体:post携带的数据
1 | GET /sample.Jsp HTTP/1.1 //请求行 |
1 | POST / HTTP1.1 |
2.3.2 响应报文
- 状态行
- 响应头
- 空行
- 响应体
1 | HTTP/1.1 200 OK //状态行 |
2.4 HTTP常见返回状态码
状态码 | 含义 | 典型例子 |
---|---|---|
1xx | 指示信息类,表示请求已接受,继续处理 | 100:继续请求 101:准备切换协议 |
2xx | 指示成功类,表示请求已成功接受 | 200:请求成功 201: 成功创建资源 204: 成功处理请求但是没有返回 |
3xx | 指示重定向,表示要完成请求必须进行更近一步的操作 | 301:请求页面永久移动到新url 302:请求页面临时移动 |
4xx | 指示客户端错误,请求有语法错误或请求无法实现 | 403:禁止,服务器拒绝请求 404:服务器找不到请求的网页 |
5xx | 指示服务器错误,服务器未能实现合法的请求 | 500:服务器内部错误 502:错误网关 503:服务器不可用 |
2.5 HTTP跨域问题
2.5.1 基本概念
【跨域】 只要协议(http/https)、域名(domin)、端口(port) 有任意一个不同就认为发生了跨域
【浏览器同源策略】
阻止一个域的javascript脚本和另外一个域的内容进行交互,具体表现为:
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
- 无法接触非同源网页的 DOM
- 无法向非同源地址发送 AJAX 请求
2.5.2 解决方案
避开浏览器的安全限制,参考这篇博客
JSONP
:通过<script src>
标签发送请求document.domin
:当主域名相同子域名不同时,可以通过设置两个页面相同的document.domin
来实现两个页面共享cookiewindow.name
:window.postMessage()
:1
2
3
4
5// 父窗口打开一个子窗口
var openWindow = window.open('http://test2.com', 'title');
// 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)
openWindow.postMessage('Nice to meet you!', 'http://test2.com');1
2
3
4
5
6// 子窗口监听 message 消息
window.addEventListener('message', function (e) {
console.log(e.source); // e.source 发送消息的窗口
console.log(e.origin); // e.origin 消息发向的网址
console.log(e.data); // e.data 发送的消息
},false);CORS
:开启跨域资源共享,允许通过的url(使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain)上的Web应用被准许访问来自不同源服务器上的指定的资源)proxy
:nginx配置反向代理。原理:浏览器有同源策略,使用服务器向另一个服务器发送请求,然后将另一个服务器的响应返回客户端websocket
:一种双向通信协议,允许客户端和服务器主动发送或接受数据(html5持久化协议)
2.6 HTTP和HTTPS联系与区别
- http 是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
- https 协议需要 ca 证书,费用较高。
- 使用不同的链接方式,端口也不同,一般,http 协议的端口为 80,https 的端口为 443。
- http 的连接很简单,是无状态的;https有状态存储
2.7 HTTPS安全传输原理
- 收方能够证实发送方的真实身份
- 发送方事后不能否认所发送过的报文
- 收方或非法者不能伪造、篡改报文
2.7.1 非对称加密算法RSA
如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密。如果用私有密钥对数据进行加密,只有用对应的公开密钥才能解密。
公钥包括在数字证书中
2.7.2 SSL建立连接
正常三次握手的过程中发送:
- 支持的加密算法
- SSL协议版本和需要访问的域名
- 一个随机数
服务器返回:
- 选中的加密算法
- SSL、TLS协议版本
- 第二个随机数
【证书验证阶段-使用非对称加密】
服务器端发送证书和公钥
【后续数据传输过程持续使用对称加密】
2.8 HTTP各版本特性
2.8.1 HTTP 1.x
【1.0】
无状态,无连接
容易发生队头阻塞:下一个请求必须在前一个请求响应之后才能发送
使用头部的协商缓存、强缓存作为缓存的判断机制
不支持断点续传,每次都会传送完整的页面
明文传输,不安全
【1.1】
提供长连接
引入etag增强缓存机制
改进队头阻塞,使用管道机制,允许不受到应答就继续发送请求(没有解决发送方队头阻塞)
支持断点续传
2.8.2 HTTP 2.x
使用https协议,提高安全性
对头部进行压缩,采用二进制传输,实现多路复用
允许服务端主动推送
2.8.3 HTTP 3.x
使用基于 UDP 的 QUIC 协议解决队头阻塞的问题
3 DNS & CDN
domin name system,域名解析系统,通过该系统将域名和ip地址一一对应
3.1 查询方式
本地域名服务器,根域名服务器,顶级域名服务器,权威域名服务器
- 递归查询:如果自己不知道,就自己发送一个请求到其他服务器,得到返回后再返回给请求的服务器
- 迭代查询:如果自己不知道,告诉请求的服务器如何去查找(向谁查找)
3.2 DNS缓存
- 浏览器缓存
- 操作系统缓存:存储在host文件中
3.3 从输入url到浏览器展示界面的过程
- url解析
- DNS查询
- 建立tcp连接
- Http请求&响应
- 渲染页面:DOM树+CSS树 => render树
3.4 CDN
内容分发网络,根据距离用户最近的位置分配资源,用户在上网的时候不用直接访问源站,而是访问离他“最近的”一个 CDN 节点,术语叫边缘节点,其实就是缓存了源站内容的代理服务器。
应用CDN后,DNS 返回的不再是 IP 地址,而是一个CNAME(Canonical Name ) 别名记录,指向CDN的全局负载均衡
3.5 url组成
- 协议
- 域名
- 端口号
- 路径
- 请求参数
- 锚点
4 浏览器
4.1 cookie & sessionStorage & localStorage
都存储在客户端
- 数据大小:cookie大小不能超过4k,其他两个可以存储5M+大小的数据
- 有效时间:cookie在有效期结束之前一直有效,localStorage永久有效(除非手动删除),sessionStorage在浏览器窗口关闭前有效(关闭后自动删除)
- 数据存储:cookie会被传输至服务端,local和session只存储在本地
详情查看js篇
4.2 缓存机制
4.2.1 强制缓存
浏览器缓存结果和缓存标识都存在,查找请求结果,根据缓存规则决定是否使用缓存
4.2.2 协商缓存
强制缓存失效,浏览器携带本地缓存标识询问服务器是否使用缓存。
命中协商缓存返回304
4.2.3 优先使用
先根据cache-control查询是否超过了有效期时间,没有超过使用强制缓存;
超过则向服务器发送请求询问是否使用缓存,服务器比较etag,返回更新的资源
【etag和last-modified】
last-modified保存上一次更新的时间,etag保存hash
last-modified只精确到秒级,并且依赖于文件修改时间,不够准确
【刷新】
刷新会导致本地文件强制过期,如果在地址栏输入url则按照正常流程查询是否过期
4.3 严格模式和混杂模式
4.4 浏览器进程和线程
关于同步、异步问题,事件循环等内容
- 浏览器主进程(一个),浏览器tab切换、回退刷新等操作
- 网络进程,负责网络资源加载(一个)
- GPU进程(一个),负责像素点绘制
- 插件进程(一个插件一个)
- 渲染进程(一个tab一个),多个tab互不影响:渲染进程中有多个线程
- GUI渲染线程
- JS引擎线程
- 事件触发线程
- 异步请求线程
- 定时触发器线程
在浏览器中打开一个网页相当于新起了一个进程(进程内有自己的多线程)
线程之间关系:gui和js互斥
5 网络攻击与安全
5.1 xss攻击
跨站脚本攻击,允许攻击者将恶意代码植入到提供给其它用户使用的页面中
注入恶意sql语句 劫持cookie
【解决方案】
在使用 .innerHTML、.outerHTML、document.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent、.setAttribute() 等
5.2 csrf攻击
攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求
【解决方案】
- 阻止不明外域的访问
- 要求提供token或双重cookie验证
5.3 ddos攻击
5.4 sql注入攻击
将恶意的 Sql查询或添加语句插入到应用的输入参数中,再在后台 Sql服务器上解析执行进行的攻击
【解决方案】
- 严格检查输入变量的类型和格式
- 过滤和转义特殊字符
- 对访问数据库的Web应用程序采用Web应用防火墙
6 Q&A
- 什么是三次握手和四次挥手?
见1.2.2节。回答要点:数据包内容+客户端、服务端状态 - http和https是什么?有什么联系和区别?
http和https是超文本传输协议,联系与区别见2.6节 - 在浏览器中输入url后到加载完整页面的过程?
见3节 - 常见的http状态码和含义?
见2.4节 - 跨域的解决方案?
见2.5节,浏览器同源策略以及避开安全限制的方法