域名劫持检测


##网站非主域遭遇运营商DNS劫持的检测 由于最近站点静床和图床专用的子域名遭到运营商的劫持,导致js ,css 和图片文件加载失败,最近用户反馈很多,目前还没有什么特别好的应对办法 老大想在网站增加一个域名检测小功能,记录相关数据,比等用户主动反馈好

###需求: 在用户访问网站遇到错误时,去分别请求CSS和JS所在域,如不正常,向后台发送日志

###解决方案: 自己经过测试和相关方案调研,从可靠性和兼容性上可以考虑用以下方式检测 对js做全局变量检测,对CSS 特定 DOM 样式检测。 从中发现个问题load成功能够用onerror或者onreadyStatechange轻松检测,失败还真不好弄, 不要轻松的说成功的对立面就是失败。

比如在用onreadystatechange事件做检测时候,成功都会走完四个状态的,但是不成功你也不知道走到那个状态就走不下去了, 所以对于不支持onerror事件的是没办法进行复查的,只能直接打点

###具体实现如下

####对应检测的css

#cssHasLoadFlag110 {
    display: none!important;
}

####dom

<div id="cssHasLoadFlag110" style="height:0;width:0;"></div>

####javascript

(function() {'use strick'
        //复查时需检测的域列表
        var domainList = ['domain1','domain2','domain3'];
        //检测的文件路径及名称
        var filePath = '/check.dns.js';
        //获取标签的非行间样式
        var getStyle = function(obj, attr) {
            if ( typeof obj == 'object') {
                if (obj.currentStyle) {
                    return obj.currentStyle[attr];
                } else {
                    return getComputedStyle(obj, false)[attr];
                };
            }
        };
        //未成功加载复查 ,对于不支持 onerror事件直接打点
        var recheck = function(url, failCallback) {
            if ('onerror' in document) {
                var head = document.getElementsByTagName('head')[0] || document.documentElement, script = document.createElement('script');
                script.onerror = function() {
                    failCallback(url);
                    script.onerror = null;
                    head.removeChild(script);
                };
                script.src = url;
                head.insertBefore(script, head.firstChild);
            } else {
                failCallback(url);
            }
        };
        var isOk = getStyle(document.getElementById('cssHasLoadFlag110'), 'display') == 'none' && window.Q;
        if (!isOk) {
            for (var i = 0, l = domainList.length; i < l; i++) {
                recheck(domainList[i] + filePath, function(url) {
                    var img = new Image();
                    img.src = '接受统计的地址?src=dns_error' + encodeURIComponent(url);
                });
            }
        }
    })()