首页 » 微语 » 正文

用js屏蔽脚本加载的网页广告

adminxgcs 2019年07月02日 微语 324 views 0

扫一扫用手机浏览

网页用手机浏览器打开之后,在bottom的位置经常有广告显示,这是由于在wifi被dns劫持的情况下导入的广告脚本种子加载出的。 



1.查找根源


知道病情才能对症下药,广告脚本种子基本上是动态创建script来加载脚本的:


var ele;

if (/\.css[^\.]*$/.test(asset.url)) {

    ele = doc.createElement("link");

    ele.type = "text/" + (asset.type || "css");

    ele.rel = "stylesheet";

    ele.href = asset.url

}

else {

    ele = doc.createElement("script");

    ele.type = "text/" + (asset.type || "javascript");

    ele.src = asset.url

}

1

2

3

4

5

6

7

8

9

10

11

12

没错,document.createElement 



2.对症下药


/**

 1. 禁用动态添加脚本,防止广告加载

 */

(function () {

    var createElement = document.createElement;

    document.createElement = function (tag) {

        switch (tag) {

            case 'script':

                console.log('禁用动态添加脚本,防止广告加载');

                break;

            default:

                return createElement.apply(this, arguments);

        }

    }

})();

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15



3.思路扩展


可能会误伤友军,比如要加载百度的脚本等,当自己需要用到这个时,可以考虑监控script.src的值的变化来过滤脚本,但是通过定义各种setter规则来监听script都会报错,所以只能换一种思路:在script被添加前做处理。


/**

 * 禁用动态添加脚本,防止广告加载

 *

 * @param valid bool? true(valid)|false(invalid)|other(off)

 * @param rule array 配置允许(valid)|不允许(invalid)的脚本规则:支持regex、string、function

 */

(function(valid, rule) {

    if(typeof Element === 'undefined') console.log('IE8以下浏览器无效');

    var origin = new RegExp('^' + location.origin),Ele = Element;

    each(['appendChild', 'insertBefore', 'insertAfter'], proxy);


    function proxy(prop) {

        var proxy_obj = Ele.prototype[prop];

        Ele.prototype[prop] = function(elem) {

            if (!elem.children.length) {

                var tag = elem.tagName.toLowerCase();

                if (tag == 'script' && isBanScript(elem)) {

                    console.log('禁用脚本:' + elem.src);

                    var substitute = document.createElement('script');

                    substitute.innerHTML = '// 禁用脚本:' + elem.src;

                    elem = substitute;

                }

            }

            return proxy_obj.apply(this, arguments);

        };

    }


    function isBanScript(script) {

        if (origin.test(script.src)) return false;

        return valid === each(rule, match);


        function match(val) {

            var type = typeof val;

            if (type === 'string') {

                if (script.src == val) return true;

            } else if (type === 'function') {

                if (val(script)) return true;

            } else {

                if (val.test(script.src)) return true;

            }

            return false;

        }

    }


    function each(arr, fn) {

        if (arr) {

            for (var i = 0, n = arr.length; i < n; i++) {

                if (fn.call(arr[i], arr[i], i) === true) return false;

            }

        }

        return true;

    }

})(true, []);

//表示有效的脚本规则列表

赞(1

本文转载自互联网,如有侵权,联系删除

发表评论