【问题标题】:How to break on localStorage changes如何打破 localStorage 的变化
【发布时间】:2018-08-12 01:02:45
【问题描述】:

我正在寻找一种方法来中断任何 localStorage 更改。我发现有一些我不知道从哪里来的神秘条目,我希望调试器中断任何更改,以便我可以检查代码。这包括:

localStorage.someKey = someValue;
localStorage["someKey"] = someValue;
localStorage.setItem("someKey", someValue);

由于在 localStorage 中有很多方法可以更改/创建条目,因此简单地覆盖 .setItem 并执行 debugger; 将不起作用。任何想法都值得赞赏。

【问题讨论】:

  • @PatrickEvans StorageEvents 不会在同一页面上发出。它仅适用于同一域中的不同页面。
  • 我会创建一个 iframe 或另一个具有相同 URL 的选项卡和一个 storage 事件的侦听器。它不会停止调试器中的原始代码,但仍然会有所帮助。
  • 一个疯狂的想法:由于 devtools 检测到这些更改(在 Chrome 中),您可以在其中设置断点:将 devtools 取消停靠到窗口中,按 CtrlShift-i 打开 devtools-for-devtools,找到代码检测 DOM 存储更改,设置断点。
  • @wOxxOm 那可能没有我想要的调用堆栈。

标签: javascript google-chrome debugging google-chrome-devtools


【解决方案1】:

不在本机 localStorage 对象上,而是在代理版本上:

Object.defineProperty(window, 'localStorage', {
  configurable: true,
  enumerable: true,
  value: new Proxy(localStorage, {
    set: function (ls, prop, value) {
      console.log(`direct assignment: ${prop} = ${value}`);
      debugger;
      ls[prop] = value;
      return true;
    },
    get: function(ls, prop) {
      // The only property access we care about is setItem. We pass
      // anything else back without complaint. But using the proxy
      // fouls 'this', setting it to this {set: fn(), get: fn()}
      // object.
      if (prop !== 'setItem') {
        if (typeof ls[prop] === 'function') {
          return ls[prop].bind(ls);
        } else {
          return ls[prop];
        }
      }
      // If you don't care about the key and value set, you can
      // drop a debugger statement here and just
      // "return ls[prop].bind(ls);"
      // Otherwise, return a custom function that does the logging
      // before calling setItem:
      return (...args) => {
        console.log(`setItem(${args.join()}) called`);
        debugger;
        ls.setItem.apply(ls, args);
      };
    }
  })
});

我们为window.localStorage 创建一个Proxy,它将拦截property assignment(处理localStorage.someKey = someValuelocalStorage["someKey"] = someValue 情况)和property access(处理localStorage.setItem("someKey", someValue) 情况)。

现在我们需要将window.localStorage 指向我们的代理,但它是只读的。但是,它仍然是可配置的!我们可以用Object.defineProperty重新定义它的价值。

【讨论】:

  • 感谢您的解决方案。有没有办法我们可以访问 Proxy#get 部分中设置的键和值?我想系统地记录它。
  • @rriemann 是的,通过在调用 setItem 时返回自定义函数。见编辑。
猜你喜欢
  • 2019-03-20
  • 2021-07-03
  • 2019-11-01
  • 2015-09-13
  • 2014-12-05
  • 2015-07-25
  • 2021-08-13
  • 2019-06-22
  • 1970-01-01
相关资源
最近更新 更多