一、解决跨域问题:
首先解释一下什么是跨域:跨域是由于浏览器同源策略所限制的一类场景。
同源:同源是指资源地址的 "协议 + 域名 + 端⼝" 三者都相同,即使两个不同域名指向了同⼀ IP 地址,也被判断为⾮同源。
同源策略:同源策略是浏览器
的一种⽤于隔离潜在恶意⽂件的重要安全保护机制 !!! (服务器没有这个策略限制)
在浏览器中,⼤部分内容都受同源策略限制,除了以下三个资源获取类型的标签:
-
<img>
-
<link>
-
<script>
如何实现跨跨域获取数据:(主要三种方式)
-
JSONP
-
CORS
-
服务器代理(webpack代理, Nginx反向代理)
-
document.domain
JSONP:利用了<script>
标签引入资源的功能,不受同源策略的限制的特性,实现跨域效果。
在本地写一个回调(callback)函数,在URL中添加callback作为params,之后在服务器把数据以参数的形式传回,然后解析script标签上的自动触发callback函数获取相应data信息。
优点:
-
实现简单
-
兼容性好
缺点:
-
只支持 GET 请求 (因为
<script>
标签只能发送 GET 请求) -
存在被 XSS 攻击的可能,缺乏安全性保证
-
需要服务端配合改造
axios中不支持 JSONP, 如果在开发中, 需要发送 JSONP 请求, 可以用 jsonp 插件
CORS (主流):跨域资源共享(Cross-origin resource sharing),利用一些额外的 HTTP 响应头来通知浏览器, 允许访问来自指定 origin 的非同源服务器上的资源。主要是浏览器和服务器进行跨域,服务器端配置access-control-allow-origin,浏览器端的origin和服务器的access-control-allow-origin字段进行对应。分为简单请求、非简单请求(询问服务器请求的域名是否在服务器可允许的列表中,以及一些头部信息,如果请求成功才发送xmlHttpRequset请求)
代理服务器
说明: 同源策略是浏览器的安全策略, 服务器与服务器之间, 没有跨域问题! 所以可以利用代理服务器转发请求!
1、开发环境的跨域问题 (使用webpack代理服务器解决)
配置 devServer 的 proxy 配置项
module.exports = {
devServer: {
// 代理配置
proxy: {
// 这里的api 表示如果我们的请求地址有/api的时候,就出触发代理机制
'/api': {
target: 'www.baidu.com', // 我们要代理请求的地址
// 路径重写
pathRewrite: {
// 路径重写 localhost:8888/api/login => www.baidu.com/api/login
'^/api': '' // 假设我们想把 localhost:8888/api/login 变成www.baidu.com/login 就需要这么做
}
},
}
}
}
2、生产环境的跨域问题 (使用 nginx 服务器代理)
nginx:反向代理服务器,代理服务器帮助我们发送请求,不会触发跨域。
document.domain:告诉页面他们的主域名是相同的,两个次级域名跨域。
二、对BFC的理解:
BFC,是"block formatting context"的缩写,块级格式化上下文。用于盒模型中布局块级盒子独立渲染区域,将处于BFC区域内的和区域外的元素进行隔离。
触发BFC的条件(满足其一即可):
-
HTML根元素
-
position 值为
absolute
或fixed
-
float 值不为
none
-
overflow 值不为
visible
-
display 值为
inline-block
、table-cell
或table-caption
应用场景:
- 防止相邻块级元素margin重叠
- 清除浮动
- 实现自适应布局
三、对flex盒子属性的理解:
在真实的应用场景中,通常会遇到各种各样不同尺⼨和分辨率的设备,为了能在所有这些设备上正常的布局我们的应用界面,就需要响应式的界⾯设计方式来满⾜这种复杂的布局需求。
flex 弹性盒模型的优势在于开发⼈员只需要声明布局应该具有的⾏为,⽽不需要给出具体的实现⽅式,浏览器负责完成实际布局,当布局涉及到不定宽度,分布对⻬的场景时,就要优先考虑弹性盒布局。
flex-direction: 调整主轴方向
row:主轴方向为水平向右 column:主轴方向为竖直向下 row-reverse:主轴方向为水平向左 column-reverse:主轴方向是竖直向上。
justify-content主要用来设置主轴方向的对齐方式
flex-start: 弹性盒子元素将向起始位置对齐 flex-end: 弹性盒子元素将向结束位置对齐。 center: 弹性盒子元素将向行中间位置对齐 space-around: 弹性盒子元素会平均地分布在行里 space-between:第一个贴左边,最后一个贴右边,其他盒子均分,保证每个盒子之间的空隙是相等的。
align-items用于调整侧轴的对齐方式
flex-start: 元素在侧轴的起始位置对齐。 flex-end: 元素在侧轴的结束位置对齐。 center: 元素在侧轴上居中对齐。 stretch: 元素的高度会被拉伸到最大(不给高度时, 才拉伸)。
flex-wrap属性控制flex容器是单行或者多行,默认不换行
nowrap: 不换行(默认),如果宽度溢出,会压缩子盒子的宽度。 wrap: 当宽度不够的时候,会换行。
align-content用来设置多行的flex容器的排列方式
flex-start: 各行向侧轴的起始位置堆叠。 flex-end: 各行向弹性盒容器的结束位置堆叠。 center: 各行向弹性盒容器的中间位置堆叠。 space-around: 各行在侧轴中平均分布。 space-between: 第一行贴上边,最后一个行贴下边,其他行在弹性盒容器中平均分布。 stretch:拉伸,不设置高度的情况下。
子元素相关语法:
align-self:可以覆盖掉align-items上的性质
四、xss攻击 :
xss攻击原理:
Cross Site Script,跨站脚本攻击。
恶意攻击者在web页面中会插入一些恶意的script代码。当用户浏览该页面的时候,那么嵌入到web页面中script代码会执行,因此会达到恶意攻击用户的目的。那么XSS攻击最主要有如下分类:反射型、存储型、及 DOM-based型。 反射性和DOM-baseed型可以归类为非持久性XSS攻击。存储型可以归类为持久性XSS攻击。
- 产生根源:输入漏洞
- 解决方法:
- cookie防盗——会模拟正常请求,所以不可行
- token代替cookie——破解协议
- 彻底预防措施:对输入源进行安全编码
五、浏览器垃圾回收:
内存周期:分为三个阶段,内存分配,内存使用,内存回收。
-
内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
-
内存使用:即读写内存,也就是使用变量、函数等
-
内存回收:使用完毕,由垃圾回收自动回收不再使用的内存
全局变量一般不会回收, 一般局部变量的的值, 不用了, 会被自动回收掉
// 为变量分配内存
let i = 11
let s = "ifcode"
// 为对象分配内存
let person = {
age: 22,
name: 'ifcode'
}
// 为函数分配内存
function sum(a, b) {
return a + b;
}
垃圾回收:核心思想就是如何判断内存是否已经不再会被使用了,如果是,就视为垃圾释放掉
常用的两种处理垃圾回收的方法:
引用计数:
看一个对象是否有指向它的引用。如果没有任何变量指向它了,说明该对象已经不再需要了。
// 创建一个对象person, person指向一块内存空间, 该内存空间的引用数 +1
let person = {
age: 22,
name: 'ifcode'
}
let p = person // 两个变量指向一块内存空间, 该内存空间的引用数为 2
person = 1 // 原来的person对象被赋值为1,对象内存空间的引用数-1,
// 但因为p指向原person对象,还剩一个对于对象空间的引用, 所以对象它不会被回收
p = null // 原person对象已经没有引用,会被回收
缺点:循环引用。如果两个对象相互引用,尽管他们已不再使用,垃圾回收器不会进行回收,导致内存泄露(无法访问也无法释放)。
标记清除法:
-
标记清除算法将“不再使用的对象”定义为“无法达到的对象”。
-
简单来说,就是从根部(在JS中就是全局对象)出发定时扫描内存中的对象。
-
凡是能从根部到达的对象,都是还需要使用的。那些无法由根部出发触及到的对象被标记为不再使用,稍后进行回收。
从这个概念可以看出,无法触及的对象包含了没有引用的对象这个概念(没有任何引用的对象也是无法触及的对象)。
六、深拷贝和浅拷贝:
浅拷贝:
如果一个对象中的属性是基本数据类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,也就是拷贝后的内容与原始内容指向了同一个内存地址,这样拷贝后的值的修改会影响到原始的值。
深拷贝:
如果一个对象中的属性是基本数据类型,拷贝的也是基本类型的值,如果属性是引用类型,就将其从内存中完整的拷贝一份出来,并且会在堆内存中开辟出一个新的区域存来进行存放,而且拷贝的对象和原始对象之间相互独立,互不影响。
七、HTTP2.0:
- 采用二进制传输,而非HTTP1.x的文本格式,解析起来更加高效
- 采用一些头部压缩技术,减少在请求和响应头中重复携带的数据,降低网络负担
- 采用服务器推送的方式,主动向客户端推送资源,提高页面加载效率
- 采用多路复用机制,减少需要创建的连接数量,降低资源占用和性能消耗
总结:
HTTP1.X 同一时间,只能并发建立 6-8 个 TCP 连接,一个连接同时只能一个请求 (虽然可以 keep-alive复用,但也得一个个来,建立连接的成本比较高, 不让一次性建立太多连接)
新版本 HTTP/2 建立一次连接就可以并发很多个请求,所以 HTTP/2 的升级大大提升了页面加载的效率。
八、promise的实现原理:
优点:
解决了函数嵌套时会产生回调地狱的问题,利用 .then 形成链式函数
缺点:
1、无法取消Promise,一旦新建它就会立即执行,无法中途取消。
2、如果不设置回调函数,promise内部抛出的错误,不会反应到外部。
3、当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。