知乎屏蔽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})就是设置是否显示提示条幅。