一次神奇的script的体验
最近在做pc官网文章页配置化的体验,需要在没有后端同学支持下,自己低成本的实现一个方案。
一期的整体的思路是通过配置文件+骨架在实现整体的配置化方案
二期的整体思路是做本地的可视化工具/在线可视化工具来实现可配置化
为啥不用富文本的方案?
有人会好奇,富文本编辑器不香嘛?为啥要有这种方案?
答案是:成本。低成本的解决问题,我觉得才是一个工程师的价值所在,本身官网的更新是低频的,需求上不需要特别个性化的文章,大部分文章都能是类似的结构,数据本身是可以格式化的。
从成本上来讲:
上面一期的方案开发2 人/天的工作就能解决这个问题,如果做一个完整版的富文本编辑器,可能上述的成本要 2*4/天工作量,还不算测试,如果算上的话,这个成本实在是太高了。
讲讲具体的方案
讲三个方案:
- iframe的方案
- script方案
- 跨域方案
本文当中着重讲一下前两种,跨域方案是三种当中最简单,成本最低的,最成熟的,暂时不表。
iframe方案
要做配置化,做iframe第首先想到的选择。
优点:
- 简单,无脑,使用方便
- 浏览器原生支持,每篇文章一个html使用起来相对稳定,遇到问题也能及时的扔出html顶一段时间
缺点:
- 兼容性差,尤其是ie(当文章超出iframe的高度的时候,ie下滑动条无法被完美的消除掉)
- 没办法准确的动态的计算iframe内容的高度(有跨域问题,而且即使解决了跨域问题,也没办法准确稳定的获取iframe内容的宽度)
实际的举个栗子:
由于pc官网本身部署在xx.a.com,配置文件部署在yy.a.com上,那么这就产生了跨域。iframe跨域讲的比较多的是document.domain和postMessage
两种方案都尝试了:
document.domain无效。
postMessage监听监听返回的值不稳定,而且拿到的值也并非是iframe内容的高度。
因此两种方案都不太行。
当然可以用nginx配置来做跨域,但是但是本地调试的时候总不能把localhost也加入到白名单去,所以无论是从优雅程度还是兼容性上来讲都不是好的解决方案
动态script方案
动态script的方案本质上类似JSONP,但是又不太一样。
核心的思想是去动态的插入scirpt来拿到配置项js,然后挂到window上,通过window在全局共享此配置项,从而达到目的。
实际的代码类似这样
(function () {
var scp = document.createElement("script");
scp.src = 'https://static.shanzhen.me/article/listInfo.js';
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(scp, s);
scp.onload = function () {
// 核心业务代码
}
})();
script的方案优缺点:
优点:
- 使用方便,简单
- 相对比较稳定,无跨域问题
缺点:
- 执行时机本身不确定,需要做补偿机制
- 理解成本较高,接手的人需要去在服务器上翻找配置代码。
虽然动态script的方案也有一定的成本,但是相对iframe的方案要好的多,理解起来相对简单,坑也没那么多。
需要注意的是,业务代码必须写入到scp.onload当中,因为script去链接服务器资源的地址,本质上是执行了一次get请求,只有在onload的时候才能确定get请求回来的,这点很重要。
跨域的方案
直接在nginx当中配置白名单,在官网项目当中用ajax去读取对应的服务器静态资源文件,进而拿到对应的json文件
大致的代码可以这样
this.$https(NORMALURL).then({
// 业务逻辑
})
跨域的方案,几乎没什么缺点,每个页面都可以单独的请求静态资源服务器,也不会因为资源加载的顺序,而对业务造成什么影响,不同页面之间也不需要共享变量,类似调接口。