知乎屏蔽AdBlock原理
在知乎的main.app.e081f97c6d9521b4b613.js 里有以下这段代码。
var y = "AdblockBanner::dismiss",
v = function(e) {
function t() {
var e, n, r, i;
o(this, t);
for(var u = arguments.length, l = Array(u), s = 0; s < u; s++) l[s] = arguments[s];
return n = r = a(this, (e = t.__proto__ || Object.getPrototypeOf(t)).call.apply(e, [this].concat(l))), r.state = {
shown: !1
}, r.handleClose = function() {
localStorage.setItem(y, "true"), r.setState({
shown: !1
})
}, i = n, a(r, i)
}
return i(t, e), s(t, [{
key: "componentDidMount",
value: function() {
"true" !== localStorage.getItem(y) && !l() && u() && this.setState({
shown: !0
})
}
}, {
key: "render",
value: function() {
return this.state.shown && f.default.createElement("div", {
className: "AdblockBanner"
}, f.default.createElement("div", {
className: "AdblockBanner-inner"
}, "我们检测到你可能使用了 AdBlock 或 Adblock Plus,它的部分策略可能会影响到正常功能的使用(如关注)。", f.default.createElement("br", null), "你可以设定特殊规则或将知乎加入白名单,以便我们更好地提供服务。 (", f.default.createElement("a", {
href: "/question/54919485",
target: "_blank"
}, "为什么?"), ")"), f.default.createElement(m.default, {
preset: "plain",
className: "AdblockBanner-close",
onClick: this.handleClose
}, f.default.createElement(p.default, {
name: "remove"
})))
}
}]), t
}(c.Component);核心判断逻辑:
value: function() {
"true" !== localStorage.getItem(y) && !l() && u() && this.setState({
shown: !0
})
}其中localStorage.getItem(y) 就是取key为AdblockBanner::dismiss的值,l() 则是判断是否是移动端。
function l() {
return !!e.navigator && /Mobile/.test(navigator.userAgent)
}u()则是创建一个假的广告div,判断是否可以创建并显示出来
function u() {
var e = document.createElement("div");
e.className = "adsbox", document.body.appendChild(e);
var t = "none" === getComputedStyle(e).display;
return document.body.removeChild(e), t
}最后的this.setState({shown: !0})就是设置是否显示提示条幅。