很多站长会遇到一个问题, 网站加入 CNZZ 的 JS 统计代码后, Chrome 浏览器出现警告: 阻止跨站解析器阻断脚本通过 document.write 调用 (A parser-blocking, cross site script,XXXX.JS is invoked via document.write.). 该警告有时候可能会使 HTTPS 页面出现不安全因素, 甚至让使用 EV SSL 证书的网站出现不显示绿色地址栏等问题. 本文将带您找出错误原因, 解决 Chrome 对 CNZZ 统计代码报错的问题.
该警告的具体内容
通过 Chrome 开发者工具查看器中 (按 F12 查看 console), 可以查出网站是否存在这类警告 (warnings). 在网络正常的情况下, 这类报错不会影响 HTTPS 页面的展示, 但是在网络连接较差等情况下, 资源加载可能会被阻止, 从而可能导致 HTTPS 页面出现不安全因素提示.
该警告的具体内容:
A parser-blocking, cross site (i.e. different eTLD+1) script, https://s22.cnzz.com/z_stat.php?id=XXXX.js, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity.
翻译过来就是:
一个跨站解析器阻断脚本 XXXX.JS 通过 document.write 调用, 如果设备的网络连接较差, 该脚本的网络请求可能会被浏览器在此页面或未来页面加载中被阻止.
为什么会出现警告?
谷歌从 Chrome 55 版本开始干预 "通过 document.write 插入的跨站解析器阻断脚本" 的加载, 提升页面加载速度.
根据 Chromestatus 的表述, 对于诸如 2G 之类的连接速度较慢的用户来说, 通过 document.write 加载的第三方脚本, 性能损失通常非常严重, 以至于主页内容的显示会延迟数十秒.
在浏览器呈现页面之前, 必须通过解析 html 标记来构建 DOM 树. 无论何时解析器遇到脚本, 它都必须停止并执行脚本, 才能继续解析 HTML. 如果脚本动态插入另一个脚本, 解析器将被迫等待更长时间才能下载资源, 这可能会导致一次或多次网络往返并延迟首次呈现页面的时间.
Chrome 从第 55 版开始代表所有用户进行干预, 具体来说, 当满足以下所有条件时, Chrome 将不执行通过 document.write() 插入的 < script > 元素:
用户处于慢速连接, 特别是用户使用 2G 网络 (未来这种干预可能延伸到其他使用慢速连接的用户, 如慢速 3G 或 Wi-Fi).
Document.write() 在 Top 层文档中.
Document.write() 中的脚本是解析器阻断脚本. 但具有 "异步" 或 "延迟" 属性的脚本仍将正常执行.
该脚本不是托管在同一站点上. 换句话说, Chrome 浏览器不会针对匹配 eTLD+1 的脚本进行干预 (例如, 托管在 JS.example.org 上脚本插入到 www.example.org 上).
该脚本尚未在浏览器 HTTP 缓存中. 缓存中的脚本不会导致网络延迟, 所以仍会执行.
该页面的请求不是重新加载. 如果用户触发了重新加载 Chrome 不会干预, 会像平常一样执行页面.
第三方片段有时使用 Document.write() 加载脚本. 第三方通过提供异步加载替代方案, 可以允许第三方脚本加载而不会阻止页面剩余内容的显示.
解决方法
为了完整显示网站绿色地址栏, 只能放弃 CNZZ 统计功能了吗? 当然不是.
解决办法就是将网站的 CNZZ 普通 JS 代码更改为异步统计代码. 示例如下:
原统计代码:
<script src="https://s22.cnzz.com/z_stat.php?id=XXXXXXX&web_id=XXXXXX" language="JavaScript"></script>
改写为异步统计代码:
- <script>
- var cnzz_s_tag = document.createElement('script');
- cnzz_s_tag.type = 'text/javascript';
- cnzz_s_tag.async = true;
- cnzz_s_tag.charset = 'utf-8';
- cnzz_s_tag.src = 'https://w.cnzz.com/c.php?id=XXXXXXXX&async=1';
- var root_s = document.getElementsByTagName('script')[0];
- root_s.parentNode.insertBefore(cnzz_s_tag, root_s);
- </script>
请复制以上代码, 改写统计 id 后放置到需要统计的网站页面中, 需要注意: 添加好异步统计代码后, 一定要删除原来的统计代码, 否则统计数据会重复计算.
经过站点实测, 更新异步统计代码后, Chrome 对 CNZZ 统计代码的 warnings 已经消失, 网站页面和统计功能都正常. 剩下的一个 warning 是 Chrome 对百度商桥的 SSL 证书即将在赛门铁克证书制裁策略中失效的警告, 不属于本文讨论范围.
至此, Chrome 对使用 CNZZ 统计代码的 HTTPS 页面报错的问题, 就彻底解决了.
来源: https://www.cnblogs.com/SSL-https/p/cnzz-https-chrome.html