如何拦截未知名称的window.localStorage属性赋值操作?
拦截window.localStorage的新属性创建操作
可行方案:用Proxy替换原始localStorage
所有代码访问的都是window.localStorage这个全局引用,我们可以把原始localStorage用Proxy包装后重新赋值给window.localStorage,这样所有对localStorage的属性赋值(不管属性名是否提前已知)都会被拦截。
实现代码
// 保存原始localStorage的引用 const originalLocalStorage = window.localStorage; // 创建代理对象,拦截属性赋值行为 const localStorageProxy = new Proxy(originalLocalStorage, { set(target, prop, value) { // 在这里捕获新属性创建或属性修改操作 console.log(`捕获到属性赋值:${prop} = ${value}`); // 执行原始的赋值逻辑 target[prop] = value; // 返回true表示赋值操作成功完成 return true; }, // 可选:拦截属性删除操作(如果需要) deleteProperty(target, prop) { console.log(`捕获到属性删除:${prop}`); delete target[prop]; return true; } }); // 替换全局的localStorage为代理对象 window.localStorage = localStorageProxy;
验证效果
执行以下代码时,代理会自动捕获赋值操作:
localStorage.propX = 'smthg'; // 控制台输出:捕获到属性赋值:propX = smthg localStorage['propY'] = 'smthgelse'; // 控制台输出:捕获到属性赋值:propY = smthgelse
方案说明
- 因为第三方代码访问的是全局的
window.localStorage,替换为代理后,所有操作都会经过代理的拦截逻辑,完美解决无法提前知晓属性名的问题。 - 要确保这段代码在所有其他执行localStorage操作的代码之前运行,比如放在页面最顶部的
<script>标签中,或者作为最早加载的脚本。
进阶:只捕获新属性创建
如果只需要拦截新属性的创建(而非已有属性的修改),可以在set方法中增加判断:
set(target, prop, value) { const isNewProp = !target.hasOwnProperty(prop); if (isNewProp) { console.log(`捕获到新属性创建:${prop} = ${value}`); } target[prop] = value; return true; }
内容的提问来源于stack exchange,提问作者user9839468
相关产品推荐
相关产品推荐

