-
-
Notifications
You must be signed in to change notification settings - Fork 861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
不正确的iframe src输入会导致页面卡死甚至浏览器崩溃 #918
Comments
看打印日志好像是短时间多次渲染请求导致的问题,我把渲染间隔调的是300。每次不正确的请求都会导致子页面组件树渲染和API请求,我感觉是大量请求和页面渲染处理导致的性能问题,应该是SSR导致的。 我考虑是不是可以调整一下针对iframe标签渲染时机,来降低请求发送和渲染的频率解决这个问题🤧这个问题在即时渲染和所见即所得模式测试中没有出现,我定位一下问题看能不能在做一层优化🌚比如最后渲染iframe,输入过程中感觉sv模式下iframe的体验不是很好 |
已经从业务代码层优化了这个问题,谢谢 |
iframe 的渲染不太清楚要怎么组织 |
业务层处理方式以前没考虑过这个问题,调日志发现只要iframe键入src就会不断触发渲染,而且好像输入的越快这个时间就越短,会导致短时间的请求会越高,导致被迫请求的子域名不断触发组件树渲染。因为业务开启了SSR,获取数据会在组件里面有一个res的字段 useEffect(() => {
if (!res) {
history.push("/404")
}
}, [])
return (<>
{ !!res && children }
</>) 但是我感觉在别的SSR框架上可能也会导致整个页面的崩溃,如果框架开启了热更新的话。一开始准备从vditor的sv、ir和所见即所得渲染实现的差异下手,我感觉可能是sv与其它两个在渲染时机的差异(实在没有定位到源码在哪emmmm) 我想到的有两种方式,可以一定程度上解决iframe渲染的实现
第二种实现思路第二种的实现思路如下(我感觉vditor里面好像没有Lute源码renderHTML部分的实现,渲染代码块倒是有,我找了半天也可能没看到😂) 因为iframe是一个块级的元素,会生成新的节点。只要出现iframe标签就开始监听输入,但不是直接渲染,而是仅提取 当焦点失去或者监听到离开iframe输入的节点,再渲染,这样可以降低发送请求的数量。因为页面崩溃的原因并不是渲染错误,而是大量的错误堆积和大量请求的阻塞。这样降低请求网络延时的数量,性能也可以得到优化。 第一种方式实现第一种实现方式其实也可以实现iframe,不过并不是直接插入iframe的HTML了 ```iframe
// 遵循toml的语法(改成JSON也可以,只是写起来会很麻烦)
// 属性为标准的iframe的属性,渲染时机触发与上面相同
src=""
width=""
content="" // content是指可能的子节点
``` 转化为 <iframe src="" width="">{content}</iframe> 这种方式最大的好处在于可以很好的兼容现有的lute引擎在代码块层面的渲染逻辑(同时需要过滤掉lute里面的renderHTML对于这个iframe的渲染),而且前端的改动不是很大。并且使用配置项可以一步到位支持iframe的src的域名安全过滤,避免用户对业务造成比较大的影响 在我目前的业务(重构之后的版本暂未开源,之后可能会开源)层面通过正则实现了安全过滤,通过 下面是正则表达式 const iframeRegexp = /<iframe\s*src=["|'](.*?)["|']\s*><\/iframe>/g
const httpUrlRegexp = /[https?:]?\/\/(\S[^\/]*)/ 校验方法 /**
* 检查文本的iframe的src是否输入合法域
* @param raw 源文本
*/
export const check4Iframe = (raw: string): Array<boolean | string> => {
const ans = iframeRegexp.exec(raw)
if (!ans) return [true]
// 提取域名
const url = httpUrlRegexp.exec(ans[1])
if (!url) return [true]
// 不属于允许的iframe domain
if (!allowDomainList.includes(url[1])) return [false, url[1]]
return [false, ""]
} 核心思想
iframe目前还不在文档里,我怕有些业务会用这个导致体验可能会不太好。 |
其实我不太清楚 ssr 为什么会拦截 iframe 的请求并且去触发渲染,按道理他应该负责服务端渲染而已,用户的输入已经在客服端了,不应该会产生影响。 |
其实是这样的过程,客户端的vditor渲染iframe导致了其不断发送GET请求,获取iframe内部的页面。vditor编辑器所在页面路由如果是 因为iframe是一个内嵌的页面窗口,这样会触发SSR渲染iframe里面的页面,渲染完成一次大概需要300多ms,issue的截图里面有日志 |
有没有 ssr 和 iframe 渲染的配置项之类的,要不这不科学。 |
没emmmm,就是完全最基础的。。。我在准备测这可能导致的安全问题,iframe确实是在客户端渲染的,只是他的GET触发了页面渲染😂就感觉跟套娃一样 |
那应该是你开启了options.markdown.sanitize |
默认是开的,但是吧iframe发送大量GET请求是存在的,如果目标网站有风控的话,可能会有问题了;业务层不特殊处理,会出现我上面那个问题 |
先外部处理吧,因为只要有加载,就会有问题。 |
我再另外写个库自行实现第一种方式,顺便可以给docsify之类的做拓展 |
已经实现 toml2iframe |
编辑模式
sv
分屏编辑预览模式描述问题
输入iframe标签的src属性时,如果输入的格式不是标准格式的话,会导致页面卡死、甚至浏览器崩溃(出现的场景为umi(React)框架启用SSR)
期待的结果
调整iframe标签的渲染时机,以规避即时渲染导致的不断错误请求导致页面崩溃
截屏或录像
版本信息
其他信息
The text was updated successfully, but these errors were encountered: