记录一次神奇的bug——dom的id有时也会坑人
发布于 6 年前 作者 dislido 2635 次浏览 来自 分享

使用tinymce的编辑器时,按照正常方式配置完毕后打开页面报了一大堆404
image.png
根据经验,我判断应该是有个baseURL之类的选项没有写,导致tinymce默认从根路径加载资源,不过即便如此也不应该出现两个/才对
于是我从官网上找了所有和url相关的配置尝试修改,但是404信息上显示的请求地址没有任何的变化

走投无路只能打断点看源码,经过一步步追踪之后,终于定位到了发生问题的位置

			self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL);

documentBaseURL是根路径,而baseURL是从根路径开始计算的相对路径,测试发现这里baseURL为undefined,于是向上寻找baseURL的声明与赋值位置

	// If tinymce is defined and has a base use that or use the old tinyMCEPreInit
			preInit = window.tinymce || window.tinyMCEPreInit;
			if (preInit) {
				baseURL = preInit.base || preInit.baseURL;
				suffix = preInit.suffix;
			} else {
				// Get base where the tinymce script is located
// ...

可以看出tinymce会将一个名为tinymce对象导出到window,里面包含了baseURL
在已经加载过tinymce的情况下(在源码里以window.tinymce是否存在来判断),新加载的tinymce会使用旧的tinymce的baseURL
没有加载过tinymce的情况下,会查找tinymce的script标签,根据标签的src计算baseURL
显然我之前没有加载过tinymce,但是代码竟然进入了if里而不是else里,也就是说preInit被定义过了
console.log一下,破案了 image.png 可能是出于方便开发者调试的原因,很多浏览器都会自动为有id的元素创建一个变量window[dom.id] = dom,而我习惯性地给tinymce容器起了tinymce这个id,于是tinymce初始化的时候访问window.tinymce就会拿到这个元素并错误的把它当成了初始化过的tinymce创建的对象,然后从这个对象上获取baseURL值(undefined)而且没有做检查,结果就得到了错误的baseURL导致了这个bug
修改了tinymce容器的id,果然正常的加载了编辑器。。。

1 回复

如果tinymce有d.ts就好查了

回到顶部