为解决编译耗时问题,选择通过 Node.js C++ Addon 方式实现轻量版模拟。通过 addon,可以在任何环境中直接导入 const addon = require('./addon') 即可使用。这个./addon 是编译好的 addon.node 扩展。
为什么 document.all 这么难模拟?
document.all 是 IE4 时代的遗留产物。为了兼容旧网页,现代浏览器(Chrome/Firefox)保留了它,但为了不鼓励开发者使用,W3C 和浏览器厂商搞了一个非常反直觉的设计:'Undetectable'特性。
在 Chrome 控制台里试一下就知道有多诡异:
// 既存在,又不存在
typeof document.all === 'undefined' // true
document.all === undefined // false (严格相等)
document.all == undefined // true (宽松相等)
// 看起来是 falsy,但能取值
if(document.all){/* 不会执行 */}
document.all.length // 正常返回数字
document.all[0] // 正常返回元素
这就是 Node.js 纯 JS 模拟的死穴。
无论怎么用 Proxy 拦截,或者用 Object.defineProperty,在 JS 层面你永远无法让一个对象的 typeof 变成 'undefined'。JSDOM 至今没有完美支持这一点(它返回的是 'object'),这就是很多反爬脚本检测 JSDOM 的核心依据。
常见的检测逻辑
对方想抓你,只需要一行代码:
// 绝杀检测
if(typeof document.all !== 'undefined' && document.all) {
.();
}


