我们都遇到过这种情况。访问一个网站,却突然弹出一个 modal,看起来就像下面这样

对我来说,这会引发一种本能反应:诅咒他们获得了一个页面浏览量,关闭标签页,永不再访问。但也有可能我们确实想获取 modal 后面的信息。 因此,在这种情况下,下一步就是打开开发者工具,删除 modal 和 overlay,顺便可能还会删除一些其他使页面混乱的无用东西。
从这里开始,这个页面就变得有点邪恶了。
我们可能无法通过“检查元素”访问开发者工具,因为上下文菜单可能被禁用。这个很容易,他们只需要一行代码
addEventListener('contextmenu', e => e.preventDefault(), false);
但是,没关系,我们可以使用键盘快捷键,对吧?没错……除非有一段类似于下面代码的 JavaScript 正在运行
addEventListener('keydown', e => {
if(e.keyCode === 123 /* F12: Chrome, Edge dev tools */ ||
(e.shiftKey && e.ctrlKey && (
e.keyCode === 73 /* + I: Chrome, FF dev tools */ ||
e.keyCode === 67 /* + C: Chrome, FF inspect el */ ||
e.keyCode === 74 /* + J: Chrome, FF console */ ||
e.keyCode === 75 /* + K: FF web console */ ||
e.keyCode === 83 /* + S: FF debugger */ ||
e.keyCode === 69 /* + E: FF network */ ||
e.keyCode === 77 /* + M: FF responsive design mode */)) ||
(e.shiftKey && (
e.keyCode === 118 /* + F5: Firefox style editor */ ||
e.keyCode === 116 /* + F5: Firefox performance */)) ||
(e.ctrlKey && e.keyCode === 85 /* + U: Chrome, FF view source */)) {
e.preventDefault();
}
}, false);
尽管如此,浏览器菜单还是无法操作的。这最终会为我们打开开发者工具!万岁!删除那些可怕的节点,然后……看到页面刷新了,因为有一个 mutation observer 正在监视此类操作。就像下面这段代码一样
addEventListener('DOMContentLoaded', e => {
let observer = new MutationObserver((records) => {
let reload = false;
records.forEach((record) => {
record.removedNodes.forEach((node) => {
if(node.id === 'overlay' && !validCustomer())
reload = true;
});
if(reload)
window.location.reload(true);
});
});
observer.observe(
document.documentElement, {
attributes: true,
childList: true,
subtree: true,
attributeOldValue: true,
characterData: true
}
);
});
“这是战争!”模式启动!好吧,那就修改 modal 和 overlay 的样式!但是,所有样式都是内联的,并且在顶部使用了!important
,因此如果没有修改style
属性,我们就无法覆盖所有样式。

有些人可能还记得 256 个类如何覆盖一个 id,但与此同时,WebKit 浏览器已经改变了这一点(不过在 Edge 和 Firefox 中仍然存在),并且256 个 ID 从未能够覆盖内联样式。
好吧,那就修改style
属性。但是,另一个“惊喜”在等着我们:还有一段 JavaScript 正在监视属性更改
if(record.type === 'attributes' &&
(record.target.matches &&
record.target.matches('body, #content, #overlay')) &&
record.attributeName === 'style' && !validCustomer())
reload = true;
因此,除非有一些样式可以帮助我们移除 overlay,而编写这个糟糕代码的人没有设置内联样式,否则我们无法通过修改style
属性来解决这个问题。
首先要查找的是display
属性,因为将其在 overlay 上设置为none
可以解决所有问题。然后是position
和z-index
的组合。即使这些属性在实际的 overlay 上是内联设置的,如果它们没有在 overlay 下方的实际内容上内联设置,那么我们可以选择为内容设置更高的z-index
值规则,并将其置于 overlay 之上。但是,不太可能有人会错过设置这些属性。
如果偏移量(top
、right
、bottom
、left
)不是内联设置的,它们可以帮助我们将 overlay 移出页面,margin
或translate
属性也是如此。类似地,即使它们在 overlay 上是内联设置的,但没有在实际内容上和 overlay 和内容的父元素上内联设置,那么我们可以通过类似于100vw
的东西横向移动该父元素,然后将内容移回视图中。
归根结底,即使是opacity
和pointer-events
的组合也可以奏效。
但是,如果编写恼人 overlay 的人没有错过设置任何这些内联样式,并且我们有那段 JS 代码……我们无法修改内联样式而不导致页面重新加载。
但是等等!有一些东西可以使用!important
覆盖内联值,很多人都可能忽略了它……那就是@keyframe
动画!在新的或已存在的style
元素中添加以下 CSS 代码,可以将 overlay 和 modal 置于实际内容之后
#overlay { animation: a 1s infinite }
@keyframes a { { 0%, to { z-index: -1 } } }
但是,可能有一段 JavaScript 阻止我们添加新的style
或link
元素(以引用外部样式表)或修改已存在的元素以包含上述 CSS 代码,如此处所示。
if(record.type === 'characterData' &&
record.target.parentNode.tagName.toLowerCase() === 'style')
reload = true;
record.addedNodes.forEach((node) => {
if(node.matches &&
node.matches('style:not([data-href]), link[rel="stylesheet"]'))
reload = true;
});
查看 Ana Tudor 在 CodePen 上创建的 Pen 如何作恶(但请不要)(@thebabydino)。
但是,如果已经存在一个外部样式表,我们可以在其中添加我们的 CSS 代码,并且除了在requestAnimationFrame
循环中检查更改之外,没有办法检测到此类更改(有人谈论过样式变异观察器,但目前我们还没有任何此类功能)。
当然,animation
属性也可以内联设置为none
,这将阻止我们使用此解决方法。
但在这种情况下,我们仍然可以禁用 JavaScript 并删除 overlay 和 modal。或者只需通过浏览器菜单查看页面源代码。底线是:如果内容已经存在,位于 overlay 后面,那么绝对没有办法阻止访问它。但尝试这样做肯定会让人诅咒你。
我写这篇文章是因为我最近确实遇到了类似的事情。我最终获得了内容。只是花费了更多时间,并且让我讨厌编写该代码的人。
有人可能会争辩说,这些 overlay 在阻止非技术人员方面非常有效,非技术人员占网站访问者的绝大多数,但当他们费尽心思地阻止打开开发者工具、删除节点、更改样式等,并将执行此操作的整个 JavaScript 代码打包成十六进制时,他们试图阻止的不仅仅是非技术人员。
如果他们开始禁用开发者工具,我会点击后退按钮,然后转到搜索结果中的下一个结果。
或者在进入之前就打开开发者工具
伙计,你真的喜欢痛苦!简单点
window.reload = function() { /* 什么也不做 */ }
啊,但是
window.location.reload
既不可写也不可配置。如果你只想读取数据,那么你可以打开开发者工具并在调试器中触发一个事件,然后禁用暂停状态覆盖(Chrome)。现在页面完全属于你,你可以更改任何内容,而无需执行任何 JavaScript。
这实际上也很聪明。评论中有很多很棒的答案。我认为文章本身更多的是试图展示 CSS 的一些有趣特性,而不是真正解决从被 modal 阻止的页面获取内容的问题。
更改内容部分的 id。
删除内联样式。
删除 modal overlay 节点。
完成。
读到一半的时候……
哼,这太简单了,见过很多次了。
我只需在按下 F12 之前点击地址栏。
然后检查 overlay 元素,像往常一样,只需按下删除键……砰!页面重新加载!等等,什么?!
嗯,这是新的……我想我需要阅读文章的其余部分:D
禁用 JavaScript 要简单得多。我有一个 Chrome 插件,可以让我根据网站逐个切换 JavaScript 的开启和关闭。在新闻和粉丝维基网站上特别有用。如果仍然需要,可以删除元素,因为没有 JavaScript 监听器在运行。理论上,他们可以通过 Ajax 加载内容,但通常他们会担心,如果内容不在文档中,谷歌将无法抓取内容。
完全正确
<noscript><meta http-equiv="refresh" content="0; url=pay-us.html" /></noscript>
另一种解决方法是使用浏览器中的用户样式表,可能大多数样式都标记为 !important 以覆盖站点的 !important 样式。
对这些糟糕做法的深入探讨真是令人着迷!这段代码似乎讨厌任何自动向页面添加片段/脚本的浏览器扩展。
通过向样式表添加条目,还可以使用一些其他解决方法
#overlay { filter: opacity(0%); }
或#overlay { border-left: solid 100vw transparent; }
以隐藏 overlay,#overlay { pointer-events: none; }
以允许点击后面的内容。body { position: absolute; top: -1% }
然后调整top
值以滚动对于邪恶的开发者来说,添加防止这些方法的保护措施很容易,我想,但如果你遇到困难,值得一试。
我想知道谷歌需要多长时间才能检测到这些技术,并对这些网站施加严厉的 SEO 处罚。
我相信它们已经实现了,至少在移动设备上是这样的:https://webmasters.googleblog.com/2016/08/helping-users-easily-access-content-on.html
哇。为了让人感到厌烦,真是费了不少劲。
这是我的解决方案
手动打开开发者工具到元素面板。
使用“选择元素”工具选择 Pen iframe 中的一个元素。
查看 DOMContentLoaded 监听器,看看哪个监听器很糟糕(也可以通过源代码查找
reload
)。在第 30 行(
if (reload) ...
)设置断点。删除模态框
在断点处在控制台中运行
reload = false
并继续执行。你也可以在安装 MutationObserver 的地方设置断点,让页面重新加载一次,然后在下一次运行时,在安装 MutationObserver 后立即从控制台中取消它。然后你就可以随意滥用 DOM 了。
我的第一次尝试是将
window.location.reload
替换为一个空操作,但它既不可写也不可配置。更改覆盖层的 ID 允许你删除它,就像很多人说的那样,但我注意到没有人提到让主体内容可滚动。更改元素的内联样式会导致页面重新加载,但我能够通过编辑 HTML 并将 body 的所有内容包装在一个 div 中来解决这个问题,然后将其设置为
height: 100vh;
overflow-y: scroll;
你也可以只设置
<html>
标签的样式将自定义样式表关联到网站不是更容易吗?我使用 Stylish 来做这个,效果很好。移除付费墙的 CSS 示例:https://userstyles.org/styles/browse?search_terms=remove%20paywall
服务器端渲染 - 这里没什么可看的,请便 :)
我发现 Safari、Firefox 和 Edge 中的阅读视图在这种情况下非常有用。他们对此无能为力。
我会尝试使用浏览器扩展。我已经安装了 TamperMonkey 和 Stylish,可以使用其中一个注入一些可以操作弹出窗口的内容。
或者也许我会尝试在 Lynx 中打开页面。 :)
酷文章!如果我想查看页面代码,我只需查看源代码,通常这些都不值得关注!
超级有趣的文章!我遇到过类似的弹出窗口,但如果我真的很想查看内容,我一直能够通过 DevTools 删除它们。
另一个简单的解决方法是,如果他们要求输入电子邮件地址,只需输入
[email protected]
这样你就可以让他们注册自己的时事通讯,然后阅读内容!或者像其他人建议的那样,只需访问另一个网站。当他们的跳出率上升时,他们很快就会明白。对我来说,当模态框后面实际上不是实际内容,而是一张模糊的静态图像时,这尤其令人厌恶。该死的,聪明的开发者们!
你也可以使用像 Charles 这样的代理服务。下载他们的 JavaScript 文件,删除监视变异的代码行,并用你自己的版本替换它们。我更喜欢这种方法而不是完全关闭 JavaScript,这样我就可以继续使用可能使用 JS 进行路由或其他积极功能的网站。
我的解决方案是打开开发者工具,然后禁用 JS。重新加载页面,然后删除该元素。
如果网站是 SPA 并且依赖于 JS,则此方法无效。在这种情况下,需要设置断点。
另一个简单的解决方法是,如果他们要求输入电子邮件地址,只需输入 [email protected] 这样你就可以让他们注册自己的时事通讯,然后阅读内容!或者像其他人建议的那样,只需访问另一个网站。当他们的跳出率上升时,他们很快就会明白。
如果你很坏,你也可以
在任何试图打开开发者工具的人尝试时立即重新加载页面(使用 getter 的控制台错误)。
当页面底部的内容显示时(通过滚动?)并且弹出窗口“可见”时重新加载页面。
如果弹出窗口的坐标变得不正确,则重新加载页面
如果你想阅读文章,而你不能简单地禁用 javascript(因为你需要等待 ajax 内容的传递),你可以尝试以下操作
为该网站编写一些扩展程序,在需要时生成“警报”。警报会停止 js 线程。此时,你可以打开 chrome 开发者工具,而不会立即重新加载页面(getter 对象的 console.log 错误)。
只需复制页面的全部 html 并粘贴到任何你想要的地方。
阅读它,享受吧 :)
此外,你还可以通过 wire-shark 监控 xhr 网络请求。或者你的扩展程序可以复制并将 body.innerHTML 发送到你的服务器。你也可以简单地禁用自定义 js 文件,你可以代理此网站并在运行时替换 js 查询内容。你可以做很多事情。你可以在加载恶意网站之前打开开发者工具。总结:坏人无法禁止你访问他的公共内容 :)
但是……浏览器存在错误。其中一些是严重的。如果这个人很坏,也许他知道其中一些。他可以通过零日漏洞破坏你的系统? :)
附注:抱歉我的英语不好
为什么不只是禁用该网站的 JavaScript 呢?
不错,我不知道这些“技巧”中的一半。
一种隐藏它们而不会触发变异事件等的方法是在 DevTools 中选择元素并按“H”让 Chrome 隐藏它们,这应该可以在内联 !important 样式的情况下工作。
只需打开文章中提供的 codepen,你就可以看到“隐藏元素”选项仍然会重新加载页面,因此它不是解决方案。
为什么不简单地使用菜单 > 查看 > 禁用 CSS 样式(或者你的浏览器将其隐藏在任何地方)?它可能与阅读视图一样有效。
现在,你多久会做所有这些工作,然后意识到这个覆盖层后面的内容毫无价值呢?
你可能可以使用动画 API
破解它很有趣,但我只是打开 DevTols,网络选项卡,过滤内容,例如媒体,右键单击,在新选项卡中打开。
这……毫无疑问,是我 20 年来读过的最具思想性和娱乐性的文章和评论。
这里很多答案都遵循这样的思路:“附加一个样式表/删除一个脚本/更改该属性/样式”或者只是为特定网站提供解决方案。
但重点不在于那个网站:而是网站想要你看到那个模态框,并且会不遗余力地做到这一点的更普遍的问题。简而言之,假设你无法以任何方式触碰 DOM。那么,我们能做什么呢?
Stylish 不在考虑范围内。一个解决方案是使用 Grease/TamperMonkey 将一些 CSS 规则注入到现有的样式表中,但它们无法让你免受内联样式的影响。
另一个可以解决问题的不错的扩展是 uMatrix,它可以有选择地禁用脚本。虽然不太容易使用,但结果可能会有所不同。
一个不错的技巧需要篡改 DOM 方法,如
appendChild
等,甚至覆盖像setTimeout
或MutationObserver
这样的函数或类,具体取决于情况。当然,这也会破坏页面的其他部分,但这是一个很好的起点,可以了解如何定位真正的罪魁祸首。我已经这样做了太久了。反广告拦截器是最糟糕的……
不错的挑战!
在每个
reload = true
处添加断点,然后在执行停止在其中一个reload=true
时删除节点,现在通过开发者工具单步执行,并通过控制台将reload=false
,这样就可以工作了。我欣赏那个无聊的开发人员的奉献精神。
只需更改ID并更改任何您想要的内联CSS。
哈哈,这篇文章和随后的对话太棒了。每个人都讨厌这样做的网站。多年来,我一直使用控制台/开发者工具来绕过这种愚蠢的行为。特别烦人的广告?F12>找到有问题的节点>DEL。无法停止播放视频的视频容器?F12>找到有问题的iframe>DEL。上面有人提到了断点>暂停方法,另一个人提到了F12>Sources>找到媒体节点>在新窗口中打开的方法……更改对象位置、页面布局、ID值、添加/修改样式、用顶级管理员电子邮件地址轰炸模态中的注册表单,这些东西太搞笑了。我已经使用其中几种方法来击败像问题中的模态这样的有害垃圾。我认为更有趣的是Ana Tudor写了这个(向Ana致敬,感谢她的多边形动画和对超越凡人数学的运用!)。
这篇文章让我想起了90年代后期的客户请求“防止访问者查看源代码”——什么?为什么呢?你的代码里有什么邪恶的、危险的、珍贵的东西吗?你试图在渲染的代码中隐藏国家机密吗?
在获得我们想要的内容并永远放弃有问题的网站之前,我们必须问问自己:使用这种“内容受愚蠢保护”模型的网站是否真的值得我们花时间访问,或者我们是否更好地寻找替代内容来源?某些内容只能从一个提供商那里获得,但这种永久模态的东西不值得我花时间,而且它们的内容可能也不值得我花时间。
我从来不明白为什么有人会在访问者开始阅读你的内容之前,就用模态(订阅!等等等等)打他们的脸。
这更邪恶。
然后有一些像福布斯这样的网站,它们会强迫你观看广告,但不能确保你不会收到嵌入恶意软件和恶意代码的广告。如果我不能相对轻松地使用开发者工具来阅读内容,我就直接离开。没有哪种内容是如此珍贵和特殊,以至于我需要冒恶意软件的风险或被垃圾邮件骚扰。是的,我明白人们需要为制作内容付费,也有一些内容网站我付费使用,因为我经常访问。但它们很少。
element.style {
overflow: scroll;
height: 100%;
}
再见文章付费墙,对不起作者们
简单。关闭标签页,永远不要再访问他们的网站。
简单:只需使用
clip: rect(1px, 1px, 2px, 2px);
为模态设置样式。