事情的起因是这样的:
最近在新版2.0社区开发时,发现了一个很有意思的问题,字体文件会在一些情况下无法加载,所以就对着这个Bug开始着手解决,结果竟掏了360的底...
问题情况如图所示(由于我很懒,已经修复了问题,不想再来一遍,这里用网图)
我们可以从中看到,帖子页面字体有错位,并且字体号变大了。
全网搜索下来没有一位前人解决了这个问题,于是只好自己动手丰衣足食,先F12切入开发者工具看看报错内容:
为看不懂的小伙伴翻译一下: 黄色字体: 解析器阻塞、跨站点(即不同的eTLD 1)脚本,https://s.ssl.qhres2.com/ssl/ab77b6ea7f3fbf79.js,通过document.write调用。由于网络连接不良,浏览器可能会在当前或将来的页面加载中阻止此脚本的网络请求。如果在此页面加载中被阻止,将在随后的控制台消息中确认。请在https://www.chromestatus.com/feature/5718547946799104 了解详情。 红色字体: ab77b6ea7f3fbf79.js:1未捕获类型错误:无法读取未定义的属性
根据一般流程,我们先来确认这个JS来源“qhres2.com”。
emmm,原来是360搜索的,我们来看JS的具体内容.....
代码语言:javascript复制(function(e) { function t(e) { var t = location.href , n = t.split("").reverse() , r = e.split("") , i = []; for (var s = 0, o = 16; s < o; s ) i.push(r[s] (n[s] || "")); return i.join("") } var n = /([http|https]://[a-zA-Z0-9_.] .so.com)/gi , r = e.location.href; if (r && !n.test(r) && window.navigator.appName) { var i = "//s.360.cn/so/zz.gif" , s = document.getElementById("sozz") , o = s.src.split("?")[1] , u = t(o) , a = new Image; r && (i = "?url=" encodeURIComponent(r)), o && (i = "&sid=" o), u && (i = "&token=" u), o && (a.src = i) }})(window);
具体分析
这里我处理了下,以便简化代码
- 判断当前链接不是360搜索的链接 /([http|https]://[a-zA-Z0-9_.] .so.com)/gi.test(window.location.href)//返回 false
- 从js提交链接提前sid // <script src=""https://s.ssl.qhres2.com/ssl/ab77b6ea7f3fbf79.js" id="sozz"></script>let sid = document.getElementById("sozz").src.split("?")[1]// 返回 undefined
- 拼接 token
- 把 location.href 字符串倒转成 t
- 取倒转后的字符串 t 前16位,不足16为视为 “”
- 每次取sid和t各一个字符,拼接成Token。
// e = sid var t = location.href , n = t.split("").reverse() , r = e.split("") , i = []; for (var s = 0, o = 16; s < o; s ) i.push(r[s] (n[s] || "")); return i.join("")
最后,打包参数给zz.gif
上述代码逻辑很简单,就是加载一个 gif 图片,后面缀上当前 URL 和网站标识。
那么,SID在哪?
根据 360 站长平台 官方开发文档 原文:
代码语言:javascript复制<script>(function(){var src = "https://s.ssl.qhres2.com/ssl/ab77b6ea7f3fbf79.js";document.write('<script src="' src '" id="sozz"></script>');})();</script>
然后我发现,这不就是......
消失的SID
自此,问题大概就清楚了:
很明显,document.getElementById(“sozz”).src.split("?")[1] 确实只能返回 undefined。既然sid = undefined,那么undefined.split(’?’) 自然就报错了。
360搜索的工程师们,你是来搞笑的吗?
心服口服,360 的攻城狮们真是不行啊......
解决办法?
我们上面说到了一个16位的限制,然后我手贱数了下ab77b6ea7f3fbf79
嗯?这不就是16位吗?莫非......他该长这样.......
代码语言:javascript复制<script>(function(){var src = "https://s.ssl.qhres2.com/ssl/ab77b6ea7f3fbf79.js?ab77b6ea7f3fbf79";document.write('<script src="' src '" id="sozz"></script>');})();</script>
测试
这......祝360早点倒闭吧......