更新于 

浏览器

控制台输出样式修改

1
console.log('\n' + '%c Stellar v' + stellar.version + ' %c\n' + stellar.github + '\n', 'color:#e8fafe;background:#03c7fa;padding:8px;border-radius:4px', 'margin-top:8px');

window

window.open

问题描述

window.top

现在手上是一个B/S端表格编辑器项目,支持表格的编辑、自动生成等功能,
使用了大量的iframe标签用于对组件进行模块划分,
因此当子窗口需要访问父窗口的属性或对象时,就不得不通过window.top进行访问。

获取上级窗口的API
  • window.top 获取顶层窗口对象
  • window.parent 获取父级窗口对象

性能

Chrome超级卡

问题描述

参考博客:

正在做一个大屏项目,一个页面上需要渲染8个监控视频,
再加上频繁的

  • dom动画
  • echarts图表渲染
  • threejs渲

总的来说:就是对浏览器的性能要求非常高

我一开始是用 chrome 开发的,开发到后面 8个监控视频+6个背景视频
直接卡到我怀疑人生 (裂开)

于是就各种优化,无外乎就是

  • Light House测试性能
  • 不该渲染的dom不渲染

但是无论怎么优化都很卡,后面干脆视频都加载不出来了。

于是我开始怀疑是浏览器的问题,
换了edge加载之后,网页加载果然流畅很多,

看到网上有很多说 关闭浏览器硬件加速 之后就好很多的,
但是我的电脑关闭硬件加速后CPU直接飙到80%、90%

后面试着用了用 firefox 加载,也很快
但是firefox的样式兼容上面是硬伤,

Edge性能监视器工具

官方文档
而且Edge的issue检测比chrome也灵敏一些,
很多chrome检测不出来的issue,Edge都会在调试台里打印出来。

跨域

CORS
Web性能权威指南
Web性能权威指南
Web性能权威指南
Web性能权威指南

前后端分离开发环境中,后台服务器响应头中 Access-Control-Allow-Origin 会一直设置为 * 状态(部分开发环境下的特例),
但在上线后,CSR模式的页面作为静态资源,这时要和后台服务在同源策略下一起被提供,
接口请求的方式也由绝对路径变为相对路径
也就是说,此时的静态资源是整个后台服务的附属资源,和接口资源处于同源之下,所以不用担心跨域的问题。

但是如果A应用的页面要调用B应用的X接口,并且B应用没有将X接口的资源设置为可跨域请求,
这时就会造成跨域,
两种常用的解决跨域的方式:

  • jsonP
  • cors
  • 代理服务器

JsonP

原理

JsonP需要服务器配合修改接口返回数据的方式,

客户端请求分为:

  • 动态请求:
    • XHR或Fetch发送的Http请求
    • 可能包含敏感信息
    • 由脚本控制
  • 静态页面资源:script标签引入的资源
    • 完全由浏览器运行
    • 不受脚本干预
    • 不包含敏感信息

所以,浏览器会对动态请求实行严格的跨域限制,对静态页面资源会更加宽松

JSONP的方式,就是将动态资源转化为静态资源请求

使用

客户端:需要将回调函数作为请求参数,将接口当做静态资源请求

1
2
3
4
5
6
7
8
9
10
11
12
<script>
function success(data){
alert('JSONP请求成功')
console.log(data)
}
function getJsonP(){
const script = document.createElement('script')
script.src = "http://10.5.6.88:4060/jsonpGet?callback=success"
document.body.append(script)
}
document.getElementById('test-jsonp').onclick = getJsonP
</script>

服务器:手动包装一个函数调用,将数据作为参数传入函数中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// jsonp
app.get('/jsonpGet',(req,res)=>{
console.log('接收到jsonp请求')
const callback = req.query.callback // 回调函数
console.log(req)
const resData = {
code:200,
message:'收到了你的请求'
}
console.log(callback)
if(callback){
let data = JSON.stringify(resData)
res.end(callback+`(${data})`) // 手动包装
}else{
res.send(resData)
}
})

Cors

原理

Cors方法需要服务器修改响应头

如果服务器主动表态:可以接受跨域获取资源,
那么跨域请求也能够实现。

这种方式就是服务器通过配置access-control-allow-origin主动开放跨域请求

实现

客户端:正常请求

1
2
3
4
5
6
7
8
9
10
<script>
function getCors(){
fetch("http://10.5.6.88:4060/corsGet",{method:'GET'}).then(res=>{
if(res.ok) return res.json()
}).then(res=>{
alert(`请求成功:${res.messasge}`)
})
}
document.getElementById('test-cors').onclick = getCors
</script>

服务器:将响应头中的access-control-allow-origin开放:

1
2
3
4
5
6
7
app.get('/corsGet',(req,res)=>{
res.setHeader('access-control-allow-origin','*')
res.send({
code:200,
messasge:'我允许你跨域请求资源'
})
})

代理服务器

原理

同源策略是浏览器限制的,那只要不经过浏览器发送请求就行,
这时候加入一个第三方代理服务器,也能够绕过同源策略

实现

客户端:正常向代理服务器发起请求

1
2
3
4
5
6
7
8
9
10
<script>
function getCors(){
fetch("http://10.5.6.88:4060/third",{method:'GET'}).then(res=>{
if(res.ok) return res.json()
}).then(res=>{
alert(`请求成功:${JSON.stringify(res)}`)
})
}
document.getElementById('test-third').onclick = getCors
</script>

服务器:向第三方发起请求,返回数据

1
2
3
4
5
6
7
8
9
10
11
12
13
const proxy_url = 'www.third.com' // 第三方地址
// 代理
app.get('/third',(req, res)=>{
res.setHeader('access-control-allow-origin','*')
axios.get(proxy_url)
.then(data=>{
console.log('转发成功')
res.send(data.data)
}).catch(err=>{
console.log('转发失败',err)
res.send(err)
})
})