对比和整理网页在window对象新增/改变的对象

21 阅读1分钟

在 document-start 和 document-end 都需要添加各自的对比代码。

document-start:

// === Step 1: 记录 baseline ===
if (!window.__baselineGlobals) {
    window.__baselineGlobals = {};

    Object.getOwnPropertyNames(window).forEach(name => {
        try {
            let desc = Object.getOwnPropertyDescriptor(window, name);
            // 保存 descriptor 和 value(如果是函数/对象只保存引用,不做深拷贝)
            window.__baselineGlobals[name] = {
                desc,
                value: window[name]
            };
        } catch (e) {
            // 某些属性可能抛异常(如跨域对象),忽略
        }
    });

    console.log("✅ 已保存 window 初始全局属性快照。刷新页面后再次运行此 Snippet 进行对比。");

}

document-end:

if (!window.__baselineGlobals) {
    //【西西 2025-09-23 152258】不应该走到这一步
    debugger;
    window.__baselineGlobals = {};

    Object.getOwnPropertyNames(window).forEach(name => {
        try {
            let desc = Object.getOwnPropertyDescriptor(window, name);
            // 保存 descriptor 和 value(如果是函数/对象只保存引用,不做深拷贝)
            window.__baselineGlobals[name] = {
                desc,
                value: window[name]
            };
        } catch (e) {
            // 某些属性可能抛异常(如跨域对象),忽略
        }
    });

    console.log("✅ 已保存 window 初始全局属性快照。刷新页面后再次运行此 Snippet 进行对比。");

} else {
    //【西西 2025-09-23 152304】走到这一步是符合预期的
    debugger;
    // === Step 2: 对比 ===
    let before = window.__baselineGlobals;
    let afterNames = Object.getOwnPropertyNames(window);

    let added = afterNames.filter(k => !before[k]);
    let removed = Object.keys(before).filter(k => !afterNames.includes(k));

    let modified = [];
    Object.keys(before).forEach(name => {
        if (afterNames.includes(name)) {
            try {
                let currentDesc = Object.getOwnPropertyDescriptor(window, name);
                let baseline = before[name];

                // 判断 descriptor 是否不同
                let descChanged = JSON.stringify(currentDesc) !== JSON.stringify(baseline.desc);

                // 判断 value 是否被替换(引用对比,不是深度内容对比)
                let valueChanged = window[name] !== baseline.value;

                if (descChanged || valueChanged) {
                    modified.push({
                        name,
                        descChanged,
                        valueChanged,
                        oldType: typeof baseline.value,
                        newType: typeof window[name]
                    });
                }
            } catch (e) {
                // 有些 getter 会报错,忽略
            }
        }
    });

    console.group("🌍 Window 全局对象变更情况");
    console.log("➕ 新增的全局变量:", added);
    console.log("➖ 被移除的全局变量:", removed);
    console.log("✏️ 被重写/修改的全局变量:", modified);
    console.groupEnd();

    // 清理快照,方便下次重新记录
    delete window.__baselineGlobals;
}