1. 从输入URL到页面加载发生了什么?
-
首先, 在浏览器地址栏中输入URL,并按下回车键
-
浏览器查找当前URL是否存在缓存, 如果缓存中有,会直接在屏幕中显示页面内容, 若缓存中没有, 则跳到下一步
-
浏览器向DNS(Domain Name System)服务器请求解析该URL中的域名对应的IP地址
-
解析出IP地址后, 根据改IP地址和默认端口80,和服务器建立TCP链接
-
浏览器发出读取文件的HTTP请求, (该请求报文作为TCP三次握手的第三个数据发送给服务器)
-
服务器对浏览器请求做出响应, 并把对应的html文本发送给浏览器
-
释放TCP链接
-
浏览器显示该HTML内容
2.浏览器如何渲染页面?
-
通过HTML解析器解析HTML文本并构建DOM tree
-
通过解析器解析CSS样式表并构建CSSOM tree
-
根据DOM tree和CSSOM tree构建Render tree
-
Render tree 刚构建完成是没有元素节点坐标, 尺寸大小信息等, 此时通过Layout进行布局处理, 计算出元素在屏幕上显示的位置, 尺寸大小信息等
-
遍历渲染树, 对每一个元素节点进行绘制。
-
浏览器会将各层的信息发送给GPU,GPU会将各层合成, 显示在屏幕上。
3.TCP三次握手
3.1 TCP三次握手的作用
三次握手其实就是指建立TCP连接时, 需要客户端和服务器总共发送3个包。
进行三次握手的主要作用:为确认双方的接收能力和发送能力是否正常, 指定自己的初始化序列号, 为后面的可靠性传输做准备。
实质上就是连接服务器指定端口、建立TCP连接。 并同步连接双方的序列号和确认号, 交换TCP窗口大小信息。
3.2 TCP三次握手过程
3.2.1 图文中字符的含义:
SYN: 连接请求/接收报文段
seq: 初始化序列号
ACK: 确认报文
ack: 确认号。希望收到下一个数据的第一个字节的序号。
3.2.2 握手过程中的状态:
- closed状态:没有任何连接
- Listen状态: 侦听来自远方TCP端口的连接请求
- SYN_SENT: 在发送连接请求后等待匹配的连接请求
- SYN_RECEIVED: 在收到和发送一个连接请求后等待对连接请求的确认
- Established: 代表一个打开的连接, 数据可以传递给用户
3.2.3 握手过程
第一次握手:
客户端给服务端发送一个SYN报文(SYN = 1), 并指明客户端的初始化序列号ISN(x) , 此时客户端处于SYN_Send状态。 此时:首部的同步位SYN = 1, 初始化序列号seq = x(SYN = 1 的报文段不能携带数据, 但要消耗掉一个序号)
第二次握手:
服务器端收到客户端的SYN报文后, 会以自己的SYN报文作为应答, 并指定自己的初始化序列号ISN(y) , 同时把客户端的ISN + 1 作为确认序列号ack的值, 表示已经收到客户端发送来的SYN报文,此时服务器处于SYN_REVD的状态。 在确认报文段中SYN = 1, ACK(确认报文) = 1, 确认号ack = x + 1,初始化序列号 seq = y
第三次握手:
客户端收到服务器端响应的SYN报文之后, 会发送一个ACK报文, 也是一样把ISN + 1 作为ack的值, 表示已经收到服务端发来的SYN报文, 此时客户端处于Establised状态, 服务器收到ACK报文之后, 也处于Establised状态, 至此,双方建立了TCP连接。确认报文ACK = 1, 确认号ack = y + 1, 序列号seq = x + 1; ACK报文段可以携带数据, 不携带数据则不消化序号。
3.3 三次握手中可以携带参数吗?
第三次握手的时候,是可以携带数据的。 但是第一次握手和第二次握手绝对不可以携带数据。如果第一次或者第二次握手携带数据的话, 如果有人恶意攻击服务器, 那么每次都在握手中的SYN报文中放入大量数据, 然后疯狂重复发送SYN报文的话, 这回让服务器花费很多时间, 内存空间来接收这些报文。
总结:请求连接/接收 即SYN = 1的时候不要携带数据。
3.4 为什么需要三次握手
三次握手的主要目的就是建立可靠的通信信道, 简单来说就是数据的发送与接收, 而三次握手最主要的目的就是双方确认自己与对方的发送与接收是否正常。
3.5 ISN(Initial Sequence Number:初始序列号)是固定的吗?
三次握手的其中一个重要的功能是客户端和服务端交换ISN, 以便让对方知道自己接下来接收数据的时候如何按照序列号组装数据。
当一端为建立连接而发送它的SYN时, 它会为连接选择一个初始序列号, ISN(初始序列号)随时间而变化, 因此每个连接都具有不同的ISN(初始序列号). 如果ISN是固定的, 攻击者很容易才出来确认号, 因此ISN是动态生成的。
3.6半连接队列
服务器第一次收到客户端的SYN之后, 就会处于SYN_RCVD状态, 此时双方还没有完全建立其连接, 服务器会把这种状态下的请求连接放在一个队列里, 我们把它称之为半连接队列。
当完成三次握手后建立的连接就会放在全连接队列中, 称为全连接队列。
3.7 SYN攻击是什么?
服务器端的资源分配是在第二次握手时分配的, 而客户端的资源是在完成第三次握手时分配的。 所以服务器容易受到SYN洪范攻击。
SYN攻击就是客户端在短时间内伪造大量不存在的IP地址, 并向服务器不断发送SYN包, 服务器则回复确认包, 并等待客户端确认。 由于源地址不存在, 因此服务器需要不断重复发确认包, 直至超时。这些伪造的SYN包将长时间占用未连接队列, 导致正常的SYN包请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。
SYN攻击是一种典型的DoS或者DDos攻击. 检测SYN攻击非常方便, 当你在服务器上看到大量的半连接状态时, 特别是源IP地址是随机的, 基本可以判断这是一次SYN攻击。 在Linux/unix 上可以使用系统自带的netstarts命令来检测SYN攻击。 netstat -n -p TCP | grep SYN_RECV 预防SYN攻击的方法:
- 缩短超时( SYN Timeourt)时间
- 增加最大半连接数
- 过滤网关防护
- SYN cookies技术
4. 四次挥手
4.1 四次挥手的作用
建立一个连接需要三次握手, 而终止一个连接要警告四次挥手。 这由TCP的半关闭造成的, 所谓的半关闭,其实 就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
TCP的连接的查出需要发送四个包, 因此称为四次挥手, 客户端或服务端均可发起挥手动作。
4.2 符号的含义:
- FIN :连接终止位
- seq:发送的第一个字节的序号
- ACK:确认报文段
- ack:确认号。希望收到的下一个数据的第一个字节的序号
4.3 四次挥手过程
第一次挥手:
客户端发送一个FIN报文(请求连接终止:FIN=1),报文中会指定一个序列号seq = u, 并停止再发送数据, 主动关闭TCP连接。进入FIN_WAIT1(终止等待1)状态, 等待服务端的确认。
第二次挥手
服务端收到FIN之后, 会发送ACK报文, 且把客户端的序号值 +1作为ACK报文的序列值, 表明已经收到客户端的报文了。此时服务端处于CLOSE_WAIT状态。
第三次挥手
如果服务端也想断开连接了(没有要和客户端发出的数据),和客户端的第一次挥手一样, 发送FIN报文, 且指定一个序列号。此时服务端处于LAST_ACK的状态。
第四次挥手
客户端收到FIN之后,一样发送一个ACK报文作为应答(ack = w + 1), 且把服务端的序列值 + 1作为自己ACK报文的序列值(seq = u + 1), 此时客户端处于TIME_WAIT状态,需要过一阵子,以确保服务端收到自己的ACK报文之后才会进入CLOSED状态。
收到一个FIN意味着再这一方向上没有数据流动。客户 端执行主动关闭并进入 TIME_WAIT 是正常的, 服务端 通常执行被动关闭, 不会进入 TIME_EAIT 状态。
4.4 为什么需要四次挥手?
因为当服务端收到客户端的SYN连接请求报文后, 可以直接发送SYN + ACK报文.其中ACK报文是用来应答的,SYN报文是用来同步的。 但是关闭连接时,当服务端收到FIN报文时,告诉客户端:你发的FIN报文我收到了,只有等到我的服务端所有的报文都发送完了, 我才能发送FIN报文, 因此不能一起发送, 故需要四次挥手。
4.5 四次挥手释放连接时, 等待2MSL的意义?
MSL是最长报文段寿命,它是任何报文再网络上存在的最长时间, 超过这个时间, 报文将被丢弃。
为了保证客户端发送的最后一个ACK报文能够到达服务器。 因为这个ACK有可能丢失, 从而导致处于LAST_ACK状态的服务器收不到FIN_ACK的确认报文。 服务器会超时传这个FIN_ACK,接着客户端再重新确认一次, 重新启动等待计时器,最后客户端和服务端都能正常关闭。
5. 你知道哪些状态码?
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
- 200 OK,表示从客户端发来的请求在服务器端被正确处理
- 204 No content,表示请求成功,但响应报文不含实体的主体部分
- 205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
- 206 Partial Content,进行范围请求
3xx:重定向–要完成请求必须进行更进一步的操作。
- 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
- 302 found,临时性重定向,表示资源临时被分配了新的 URL
- 303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源
- 304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
- 307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
4xx:客户端错误–请求有语法错误或请求无法实现。
- 400 bad request,请求报文存在语法错误
- 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
- 403 forbidden,表示对请求资源的访问被服务器拒绝
- 404 not found,表示在服务器上没有找到请求的资源
5xx:服务器端错误–服务器未能实现合法的请求。
- 500 internal sever error,表示服务器端在执行请求时发生了错误
- 501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
- 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
6. HTTP 与HTTPS
6.1 什么是HTTP
HTTP是超文本传输协议, 是一个简单的请求-响应协议, 它通常运行在TCP上,主要用于浏览器和服务器之间的通信。
6.2 什么是HTTPS
HTTPS是以安全为目标的HTTP通道, 简单讲是HTTP的安全版, 即HTTP下加了SSL层, HTTPS的安全基础是SSL, 因此加密的详细内容就是需要SSL.
6.3 HTTPS的作用
内容加密: 建立一个信息安全的通道, 来保证数据传输的安全;
身份认证: 确认网站的真实性
数据完整性: 防止内容被第三方冒充或者篡改
6.4 . HTTPS为什么让数据传输更安全?
HTTPS并不是一个新的协议,而是一个加强版的HTTP。 其原理是在HTTP和TCP之间建立了一个中间层,当HTTP和TCP通信时并不是像以前那样直接通信,而是经过一个中间层加密,将加密后的数据包传给TCP响应的,TCP必须将数据包解密,才能传给上面的HTTP.这个中间层也叫安全层。安全层的核心就是对数据加解密。
6.5 HTTP与HTTPS的区别:
- HTTPS协议需要到ca申请证书,一般免费证书很少, 需要交费。
- HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSL加密传输协议。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样。HTTP是80,HTTPS是443;
- HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
6.6 HTTPS的工作原理
HTTPS的整个过程分为证书验证阶段和数据传输阶段:
- 证书验证阶段 : HTTPS在证书验证阶段使用的是非对称加密
- 数据传输阶段 : HTTPS在内容传输阶段使用的是对称加密。
6.6.1 证书验证阶段:
- 浏览器向服务端发起HTTPS请求;
- 服务器返回HTTPS证书
- 客户端验证证书是否合法, 如果不合法则提示警告。
6.6.2 数据传输阶段
- 当证书验证合法后,在本地生成随机数;
- 通过公钥加密随机数,并把加密后的随机数传输到服务端;
- 服务端通过私钥对随机数进行解密
- 服务端通过客户端传入的随机数构造对称加密算法, 对返回结果内容进行加密后传输
6.6.3浏览器如何验证证书的合法性?
- 验证域名、有效期等信息是否正确
- 判断证书来源是否合法
- 判断证书是否被篡改
- 判断证书是否已被吊销
7. 对称加密和非对称加密:
7.1 对称加密:
是最简单的方式,指的是加密和解密用的是同样的密钥;
对称加密:发送方和接收方需要持有同一把密钥,发送消息和接收消息均使用该密钥。相对于非对称加密,对称加密具有更高的加解密速度,但双方都需要事先知道密钥,密钥在传输过程中可能会被窃取,因此安全性没有非对称加密高。
7.2 非对称加密:
非对称加密: 接收方在发送消息前需要事先生成公钥和私钥,然后将公钥发送给发送方。发送方收到公钥后,将待发送数据用公钥加密,发送给接收方。接收到收到数据后,用私钥解密。
在这个过程中,公钥负责加密,私钥负责解密,数据在传输过程中即使被截获,攻击者由于没有私钥,因此也无法破解。 非对称加密算法的加解密速度低于对称加密算法,但是安全性更高。
7.3 加解密过程:
-
(1) 首先,浏览器会给服务器发送一个随机得client_random和一个加密的方法列表;
-
(2)服务器接收到浏览器返回另一个随机数 server_random和加密方法;
-
(3)现在,两者拥有三样相同的凭证:client_random、server_random和加密方法;
-
(4)用这个加密的方法将两个随机数混合起来就生成密钥,这个密钥就是浏览器和服务端通信的 。
7.4 对称加密和非对称加密的区别:
对称加密: 加密和解密使用的是同样的密钥, 所以速度快, 但由于需要将密钥在网络传输, 所以安全性低。
非对称加密: 使用了一对密钥, 公钥和私钥, 所以安全性高, 但是加密和解密速度慢。
解决方法: 将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去, 接收方使用私钥进行解密得到对称加密的密钥, 然后双方可以使用对称加密进行沟通。
8. HTTP 方法:
8.1 HTTP请求常用方法:
- GET: 使用给定的URL从给定服务器中检索信息, 即从指定资源中请求数据。
- POST: 用于将数据发送到服务器以创建或更新资源。
- HEAD: 请求资源的头部信息,与GET方法相同, 但是没有响应体, 仅传输状态行和标题部分。
- OPTIONS: 用于获取目的的资源所支持的通信选项
- PUT: 用于新增资源或者使用请求中的有效负载替换目标资源的表现形式
- DELETE: 用于删除指定的资源
- PATCH: 用于对资源进行部分修改
- CONNECTION: HTTP/1.1协议中预留给能够将链接改为管道方式的代理服务器
- TRACE: 回显服务器收到的请求, 主要用于测试或诊断
8.2 GET VS POST
- GET在浏览器回退时是无害的,而POST会再次发起请求
- GET请求会被浏览器主动缓存,而POST不会,除非手动设置
- GET请求参数会被保留在浏览器历史记录里,而POST中的参数不会被保留
- GET请求在URL中传递的参数有长度限制(浏览器限制大小不同),而POST没有限制
- GET参数通过URL传递,POST放在Request body中
- GET产生的URL地址可以被收藏,而POST不可以
- GET没有POST安全,因为GET请求参数直接暴露在URL上,所以不能用来传递敏感信息
- GET请求只能进行URL编码,而POST支持多种编码方式
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制
- GET产生一个TCP数据包,POST产生两个数据包(Firefox只发一次)。GET浏览器把 http header和data一起发出去,响应成功200,POST先发送header,响应100 continue,再发送data,响应成功200
- get请求是幂等的, post请求是非幂等的。
8.3 PUT VS POST
PUT和POST方法的区别是:
- PUT方法是幂等的: 连续调用一次或者多次的效果相同(无副作用), 而POST方法是非幂等的
- PUT的URL指向的是具体的单一资源, 而POST可以指向资源集合。
8.4 PUT VS PATCH
PUT和patch都是资源更新, 而PATCH用来对已知资源进行局部更新。
比如修改一条数据, PUT是直接发送一条新的数据过去, 但是PATCH可以只对这条数据的某个字段进行修改。
PUT是直接资源覆盖,PATCH是局部更新。
9. TCP和UDP的区别
9.1 传输控制协议TCP
- TCP是面向链接的。 (在传送数据之前必须要建立连接, 数据传送结束后要释放连接。TCP的可靠体现在TCP在传输数据之前会有三次握手来建立连接, 而且在数据传递时, 在数据传送完之后, 还会有四次挥手来断开连接,用来节约系统资源,所以增大了很多开销 )
- 每一条TCP链接只能有两个断点, 每一条TCP链接只能是点对点(一对一)
- TCP提供可靠交付的服务(TCP的可靠体现在TCP在传输数据之前会有三次握手来建立连接, 而且在数据传递时, 会有确认、窗口、重传、拥塞控制机制, 在数据传送完之后, 还会断开连接用来节约系统资源,所以增大了很多开销
- TCP提供全双工通信。 TCP允许通信双方的应用进程在任何时候发送数据。 TCP链接的两端都设有发送缓存和接收缓存, 用来临时存放双方的通信数据;
- 面向字节流。 TCP中的流(Stream)指 的是流入进程或进程流出的字节序列。
- TCP使用的场景:文件传输、发送和接收邮件, 远程登录等等。
9.2 用户数据协议UDP
- UDP时无连接的;
- UDP使用尽最大努力交付, 即不保证可靠交付, 因此主机不需要维持复杂的链接状态
- UDP是面向报文的
- UDP没有拥塞控制, 因此网络出现拥塞不会使源主机的发送频率减低。
- UDP支持一对一、一对多、多对一以及多对多的交互通信
- UDP的首部开销小, 只有8个字节, 比TCP的20个字节的首部要短。
- UDP使用场景: qq语音、qq视频,直播等。
10. 什么是持久链接(长连接)
10.1 持久连接的概念
HTTP请求头都要经过TCP三次握手建立连接, 四次挥手断开连接, 如果每个HTTP请求都要建立TCP连接的话是及其费时间的, 请求头中的Connection:keep-alive的作用可以在请求完成后, 保持TCP连接在一段时间不关闭, 如果这个时间段又有HTTP请求的话, 直接使用这个TCP连接, 省去了建立新的连接的时间。
HTTP1.1中浏览器默认开启了Connection:keep-alive,* Connection: close关闭持久连接*。可以设置timeout, 一定时间在此TCP连接没有请求就会关闭。
同时服务端还会设置一个参数叫最大请求数, 比如:最大请求数是300, 只要请求次数超过300, 即使还没有到超时时间, 服务端也会主动关闭连接。
不同ID代表不同TCP连接, 不同域名需要分别创建TCP连接。
TCP请求的连接有先后顺序, 无法并发执行。 浏览器允许并发创建TCP,Chrome允许最多6个并发。
10.2 持久连接的优缺点
优点:
- 减少CPU及内存的使用, 因为不需要经常建立和关闭连接
- 支持管道话的请求及响应模式
- 减少网络堵塞,因为减少了TCP请求
- 减少了后续请求的响应时间, 因为不需要等待建立TCP、握手、挥手、关闭TCP的过程。
- 发生错误时,也可在不关闭连接的情况下进行错误提示。
缺点:
一个长连接建立后,* 如果一直保持连接*, 对服务器来说时多么浪费资源的事情, 而且长连接时间的长短, 直接影响到服务器的并发数。
10.3 如何避免长连接资源浪费
- 客户端请求头声明:Connection:close,本次通信后就关闭连接
- 服务端配置: 如Nginx, 设置keep-alive_timeout:设置长连接超时时间,keepAlive_requests*设置长连接请求次数上限
11. 什么是管道话(管线化)
http1.1在使用长连接的情况下, 建立一个连接通道后, 连接上的消息的传递类似于:
请求1 -> 响应1 -> 请求2 -> 响应2 -> 请求3 -> 响应3
管道话连接的消息就变成类似这样:
请求1——>请求2——>请求3——>响应1——>响应2——>响应3
管道话: 是在同一个TCP连接里发送一个请求后不必等其请求回来就可以继续发送第二个请求,这样可以减少整体的响应时间, 但是服务器还是会按照请求的顺序响应请求,所以如果有许多请求, 而前面的请求响应很慢, 就产生一个队头堵塞的问题。
如何解决对头阻塞问题:
- 并发连接:
- 因为一个域名允许分配多个长连接, 就相当于增加了任务队列, 不至于一个队列里的任务阻塞了其他全部任务。
- 域名分片:
- 一个域名最多可以并发6~8个, 那就多准备几个二级域名, 当我们访问主域名时, 可以让不同的资源从不同的二级域名中获取, 而他们都指向同一台服务器,这样就可以并发更多的长连接了。
- HTTP/2多路复用
12.Websocket
12.1 什么是Websocket?
Websocket是HTML5一种新的协议,Websocket协议解决了服务器和客户端全双工通信的问题。它的目的是在浏览器和服务器之间建立一个不受限制的双向通信的通道, 比如:服务器可以在任何时间向浏览器发送消息。Websocket本身是基于TCP协议的。
它最大的特点就是服务器可以主动向客户端发送消息, 客户端也可以主动向服务器端发送消息, 是真正的双向平等的对话, 属于服务器推送技术的一种。
12.2 单工、半双工、全双工通信的区别:
12.2.1 单工
单工数据传输: 只允许数据在一个方向上传输, 在同一时间只有一方能接收或者发送数据, 不能实现双向通信, 例如:电视、广播。
12.2.2 半双工
半双工: 客户端和服务端都可以发送和接收数据,但是不能同时发送和接收数据。例如:无线对讲机。
12.2.3 全双工
全双工数据通信: 允许数据同时在两个方向上传输, 全双工通信是两个单工通信方式的结合, 它要求发送设备和接收设备都具有独立的接收和发送能力, 在同一时间可以同时接收和发送信息,实现双向通信, 例如: 电话通信
12.3 什么时候使用websocket技术?
当我们在处理页面数据自动更新的时候, 在使用js不断的请求服务器, 查看是否有新数据,如果有就获取到新数据, 进行对页面信息的更新。但是当页面长时间没有更新数据时, 这样就会存在资源浪费的情况, 所以才会使用websocket.比如:及时通信。
12.4 websocket和socket的区别是什么?
Socket是TCP/IP网络的接口, 是为了方便使用TCP或UDP而抽象出来的一层, 是位于应用层和传输层之间的一组接口。而Websocket则不同, 它是一个完整的应用层协议, 包含一套标准的API.
12.5 HTTP与Websocket的区别?
http协议是短链接, 因为请求之后, 都会关闭连接, 下次重新请求数据, 需要再次打开连接。
Websocket协议是一种长连接, 只需要通过一次请求来初始化连接,然后所有的请求和响应都是通过这个TCP连接进行通信。
13. 什么是同源策略及限制
14 跨域通信的几种方式
14.1 同源策略
protocol(协议 ) 、domain(域名)、port(端口)三者一致。
14.2 跨域的方式
1. JSONP(只支持GET请求)
JSONP主要是利用script标签没有跨域限制的这个特性来完成的
2. window + hash + ifram
原理就是通过 url 带 hash ,通过一个非跨域的中间页面来传递数据。
3. window + domain + ifram
「该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方式」。 只需要给页面添加 document.domain ='test.com' 表示二级域名都相同就可以实现跨域。
4. window + name + ifram
window 对象的 name 属性是一个很特别的属性,当该 window 的 location 变化,然后重新加载,它的 name 属性可以依然保持不变。
5. window.postMessage
「window.postMessage()」 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为 https),端口号(443 为 https 的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。**「**window.postMessage()」 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
6. websocket
客户端和服务器之间存在持久的连接, 而且双方都可以随时开始发送数据。
7. cors(cross-origin resource sharing)跨域资源共享
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的 Web 应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器**「不同的域 、 协议或端口」请求一个资源时,资源会发起一个「跨域 HTTP 请求」**
8. nginx反向代理
保证当前域能获取到静态资源和接口。
10.Node正向代理
代理思路: 利用服务端请求不会跨域的特性, 让接口和当前站点同域。
15 常见浏览器及其内核
- -webkit-: webkit核心浏览器, chrome
- -moz-: Gecko核心浏览器, firfox
- -o-: Opera核心浏览器 Opera
- -ms-:微软的IE浏览器
16. 常见的兼容性问题
- 不同浏览器的标签默认的margin和padding不一样,* {padding:0, margin:0}
- IE6双边距bug: 快属性标签float, 又有横行的margin情况下,IE6显示的margin比设置的大
- 设置较小高度标签(一般小于10px), 在IE6,IE7中高度超出自己所设置的高度。hack:给超出高度标签设置overflow:hidden, 或设置行高line-height小于你设置的高度。
- chrome中文界面下默认会将小于12px的文本强制按照12px显示, 可通过加入css属性-webkit-transform:scale()解决, Zoom也可以解决, 但是有兼容性问题, 缩放会改变元素所占据的空间大小。
- 超链接访问后hover样式就不出现了, 被点击访问过的超链接样式不在具有hover和active了,解决方法是改变CSS属性的排列顺序:L-V-H-A=>a:link {} a:visited {} a:hover {} a:active {}
17. 重绘和回流
17.1 重绘——repaint
当页面中元素样式的改变并不影响他在文档流中的位置时(例如:color, background-color, visibility等), 浏览器会将新样式赋予给元素并重新绘制它, 这个过程称为重绘。
17.2 回流——reflow
当Render Tree(DOM) 中部分或全部元素的尺寸、结构、或某些属性发生改变时, 浏览器重新渲染部分或者全部文档的过程称为回流。
导致回流的操作: - 首次页面渲染 - 浏览器窗口发生改变 - 元素尺寸或位置发生变化 - 元素内容改变 - 增加或者删除可见的DOM元素 - 激活CSS伪类(例如: :hover)
17.3 性能影响
- 回流要比重绘消耗的性能开支更大。
- 回流必将引起重绘, 重绘不一定引起回流。
17.4 如何避免重绘和回流
17.4.1 CSS:
- 避免使用table布局
- 尽可能在DOM树的最末端改变class
- 避免设置多层内联样式
- 将动画效果应用到position属性为absolute或fixed的元素上(因为脱离文档流了, 不会影响其他元素)
17.4.2 JavaScript:
- 避免频繁操作样式, 最好一次性重写style属性, 或将样式定义为class,并一次性更改class属性
- 避免频繁操作DOM, 创建一个documentFragment, 在它上面应用所有DOM操作, 最后把它添加在文档中
- 也可以先为元素设置display:none,操作结束后再把元素显示出来, 因为在display:none的元素上进行DOM操作不会引发回流和重绘。
- 避免频繁读取会引发回流和重绘的属性。 如果确实需要多次使用, 就用一个变量缓存起来。
18. web安全 XSS与csrf
18.1 XSS
XSS( Cross-Site Scripting), 跨站脚本攻击,因为缩写与CSS重叠, 所以只能叫XSS。
跨站脚本攻击指: 是指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或JavaScript进行的一种攻击。
XSS的原理是: 恶意攻击者往web页面里面插入恶意可执行网页脚本代码, 当用户浏览该页面时, 嵌入web里面的脚本代码会被执行, 从而可以达到攻击者获取用户信息或者侵犯用户安全隐私的目的。
- 非持久型XSS
非持久形XSS漏洞,一般是通过给别人发送带有恶意脚本代码参数的URL, 当URL地址被打开时, 特有的恶意代码参数被HTML解析、执行。
- 持久型XSS(存储型XSS) 持久型 XSS 漏洞,一般存在于 Form 表单提交等交互功能,如文章留言,提交文本信息等,黑客利用的 XSS 漏洞,将内容经正常功能提交进入数据库持久保存,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。
18.2 如何预防
18.2.1 预防方法一:CSP:
CSP本质上就是建立白名单, 开发者明确告诉浏览器哪些外部资源可以加载和执行, 我们只需要配置规则, 如何拦截是由浏览器自己实现的。
通常可以设置两种来开启CSP:
- 设置HTTP Header中的Content-Security-Policy:Content-Security-Policy: default-src 'self'
- 设置Meta标签的方式:
18.2.2 预防方法二:转义字符:
用户的输入永远不可信任, 最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠等进行转义。
18.2.3 预防方法三:HttpOnly Cookie
这是预防XSS攻击窃取用户cookie最有效的预防手段, web应用程序在设置cookie时,将其属性设置为HttpOnly,就可以避免网页的cookie被客户端恶意JS获取,保护cookie信息。(大部分浏览器默认支持该功能)
18.3 CSRF
CSRF( Cross Site request Forgery):即跨站请求伪造, 是一种常见的Web攻击, 它利用用户已登录的身份,在用户毫不知情的情况下,以用户的名义完成非法操作。
原理:
18.4 如何预防CSRF?
- Get请求不对数据进行修改
- 不让第三方网站访问到用户Cookie
- 阻止第三方网站请求接口
- 请求时附带验证信息, 比如验证码或者token.
- SameSite
可以对Cookie设置SameSite属性, 该属性表示Cookie不随着跨域请求发送, 可以很大程度上减少CSRF的攻击, 但是该属性由浏览器兼容问题。
- Referer Check
通过检查HTTP包头referer的值是不是这个页面,来判断是不是CSRF攻击。
- Anti CSRF Token
这种方法比较完善。 即发送请求时在HTTP请求中以参数的形式加入一个随机产生的token, 并在服务器建立一个拦截器来验证这个token. 服务器读取浏览器当前域cookie中的这个token值, 会进行校验该请求当中的token和cookie当中的token值是否都存在且相等, 才认为这是合法的请求,否则拒绝该次服务。
- 验证码
18.5 点击劫持
点击劫持是一种视觉欺骗的攻击手段。 攻击者将需要攻击的网站通过iframe嵌套的方式嵌入自己的网页中, 并将iframe设置为透明,子页面中透出一个按钮诱导用户点击。
19. web缓存机制
19.1 浏览器缓存介绍
浏览器缓存机制也就是我们说的HTTP缓存机制,其机制是根据HTTP报文的缓存表示进行的。
19.2 浏览器缓存过程
浏览器与服务器通信的方式为应答模式,即浏览器发起HTTP请求,服务器响应请求。 那么浏览器第一次向服务器发起该请求后拿到的请求结果, 会根据响应报文中的HTTP头的缓存表示, 决定是否缓存结果, 如果缓存, 则将请求结果和缓存标识存入浏览器缓存中。
由上图我们可以知道:
- 浏览器每次发起请求, 都会先在浏览器缓存中查找该请求的结果以及缓存标识
- 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中。
- 缓存过程一般分为强缓存和协商缓存。
19.3 强制缓存
19.3.1强制缓存的概念
强制缓存就是向浏览器缓存查找该请求结果, 并根据该结果的缓存规则来决定是否使用该缓存结果的过程。
强制缓存主要分为三种情况:
- 不存在该缓存结果和缓存标识, 强制缓存失效,则直接向服务器发送请求。
- 存在该缓存结果和缓存标识, 但是该结果已经失效, 强制缓存失效, 则使用协商缓存
- 存在该缓存结果和缓存标识, 且该结果尚未失效,强制缓存生效, 直接返回该结果。
19.3.2 强制缓存的缓存规则是什么?
当浏览器向服务器发送请求时, 服务器会将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器, 控制强制缓存的字段分别是Expries和Cache-Control, 其中Cache-Control优先级比Expries高。
19.4 协商缓存(304缓存)
19.4.1 协商缓存概念
协商缓存就是强制缓存失效后, 浏览器携带缓存标识向服务器发送请求, 由服务器根据缓存标识决定是否使用缓存的过程。
主要分为两种:
- 协商缓存生效, 返回304.
- 协商缓存失效, 返回200和请求结果
19.4.2 协商缓存的缓存规则
协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的。控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。
19.5 缓存总结
强制缓存优先于协商缓存, 若强制缓存生效,则直接使用缓存,若不生效则进行协商缓存。 协商缓存由服务器决定是否使用缓存, 若协商缓存失效, 那么代表该请求的缓存失效, 重新获取请求结果, 再次存入浏览器缓存中, 生效则返回304, 继续使用缓存。 主要过程:
19.6 浏览器缓存和本地缓存的区别
浏览器缓存: 缓存文件, 比如html、css、JS、Image、pdf等文件, 作用是提升访问速度,
本地缓存: 比如cookie、loacalstroage是http header里的一个字段, 保持一些很小的信息,编程使用的, 不会发送到服务器, 用来记录一些用户的登录状态和配置信息。
20. 浏览器本地缓存
浏览器本地缓存主要分为5种: localStroage、sessionStrage、cookie、WebSql、indexedDB
20.1 localStroage——本地存储
localStroage是HTML5提供的web存储中的一种,它是本地存储,通常将数据保存在客户端本地的硬件设备种。localStroage的存储周期是永久的,除非手动删除数据, 否则永远不会消失。
可以通过localStroage.setItem() / getItem()
设置或者读取数据。
优点:
- 扩展了cookie的存储大小,可以存放5M大小, 不同浏览器不同;
- 只存储在浏览器, 不会和服务器之间交互通信
- 解决了cookie的安全问题和性能消耗问题。
- localStroage的读写是同步的。
缺点:
- 需要手动删除保存的数据
- 只支持字符串类型, JSON类型需要使用JSON.stringify()转化。
- 受同源策略限制
使用场景: 常用于长期登录(判断用户是否已登录),适合长期保存在本地的数据
20.2 sessionStroage——会话存储
sessionStroage将数据保存在session对象中, 所以sessionStroage的生命周期是仅在当前会话下有效。
sessionStroage是在同源的窗口种始终存在的数据, 只要这个浏览器窗口没有被关闭, 即使刷新页面或者进入同源另一个页面, 数据依然存在。但是sessionStroage在关闭了浏览器窗口后就会被销毁。独立打开同一个窗口同一个页面,sessionStroage也是不同的。
sessionStroage的场景:sessionStroage可以用于保存一些临时的数据, 防止页面消失后数据就没有了,比如表单填写和用户的浏览器记录等。
20.3 cookie
cookie由服务端生成。 cookie就是一个存放在客户端的一个小文件, 页可以存放在本地,假设浏览器关闭之后cookie依旧存在。
cookie的设置过程:
- 客户端向服务器发送一个HTTP请求
- 服务器接收到请求后在响应头添加一个set-cookie的字段
- 客户端接收到服务器的响应后将cookie保存下来, 保存到本地的文件夹内
- 之后浏览器每一次请求都会携带cookie发送给服务器
优点:
- 记录用户的操作状态、密码等
- 弥补了HTTP的无状态
缺点:
- 容量小, 只有4kb
- 不安全, 可以随意修改cookie内容
- 耗费性能, 每一次请求都 会携带完整的cookie
20.4 web Sql
web Sql是Html5引入的数据库API, 即一组使用Sql语句操作客户端数据库的API方法。
使用场景: 面对复杂的关系型数据时,可以使用webSql.
20.5 indexedDB
indexedDB就是浏览器提供的本地数据库, 它可以被网页脚本创建和操作. indexedDB允许存储大量数据, 提供查找接口, 还能建立索引。它不属于关系型数据库。
- 数据以键值对的形式保存在对象仓库中
- 异步indexedDB操作时不会锁死浏览器,用户依然可以进行其他操作。
21. DNS域名解析
DNS即系统域名, 全程是Domain Name System。 当我们再浏览器输入一个URL地址时,浏览器要向这个URL的主机名对应的服务器发送请求, 就得到服务器得IP,对于浏览器来说,DNS得作用就是将主机名转换成IP地址。
DNS是一个应用层协议, 我们发送一个请求, 其中包含我们要查询得主机名, 它就会给我们返回这个主机名对应得IP.
其次: DNS是一个分布式数据库, 整个DNS系统由分散再世界各地得很多太DNS服务器组成,每台DNS服务器上都会保存了一些数据, 这些数据让我们最终查到主机名对应得IP.
22.简单讲解一下http2的多路复用
在HTTP/1中, 每次请求都会建立一个HTTP连接, 也就是我们常说得3次握手和4次挥手, 这个过程在一次请求过程中占用了相当长得时间,即使开启了Keep-Alive,解决了多次连接得问题, 但是依然有2个效率上得问题:
-
第一个: 串行的文件传输。当请求a文件时,b文件只能等待, 等待a连接到服务器、服务器处理文件、服务器返回文件这三个步骤。 依次类推, 后面的文件需要花费更多的时间传输。
-
第二个:连接数过多。我们假设Apache设置了最大并发数为300, 因此浏览器限制, 浏览器发起最大的最大请求数为6.
HTTP/2的多路复用就是为了解决上述的两个性能问题。 在HTTP/2中, 有2个非常重要的概念, 分别是帧(frame)和流(stream)。帧代表着最小的单据单位,每个帧会标识出该帧属于哪个流, 流也就是多个帧组成的数据流。 多路复用,就是在一个TCP连接中可以存在多条流。 换句话说, 也就是可以发送多个请求, 对端可以通过帧中的标识知道属于哪个请求。 通过这个技术,可以避免HTTP旧版本中的队头阻塞的问题, 极大的提高性能。