最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to break on localStorage changes - Stack Overflow

programmeradmin1浏览0评论

I'm looking for a way to break on any localStorage changes. I have found that there are some mysterious entries that I have no idea where that is coming from and I would like the debugger to break on any changes so that I can inspect the code. This includes:

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

Since there are so many ways to alter/create an entry in localStorage, simply overriding .setItem and do debugger; will not work. Any idea is appreciated.

I'm looking for a way to break on any localStorage changes. I have found that there are some mysterious entries that I have no idea where that is coming from and I would like the debugger to break on any changes so that I can inspect the code. This includes:

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

Since there are so many ways to alter/create an entry in localStorage, simply overriding .setItem and do debugger; will not work. Any idea is appreciated.

Share Improve this question asked Mar 4, 2018 at 5:50 Derek 朕會功夫Derek 朕會功夫 94.3k45 gold badges195 silver badges253 bronze badges 4
  • @PatrickEvans StorageEvents will not be emitted on the same page. It's only for different pages that are on the same domain. – Derek 朕會功夫 Commented Mar 4, 2018 at 6:07
  • I would create an iframe or another tab with the same URL and a listener for storage event. It wouldn't stop the original code in the debugger but still could be helpful. – woxxom Commented Mar 4, 2018 at 8:47
  • A crazy idea: since devtools detects these changes (in Chrome) you can set a breakpoint inside it: undock devtools into a window, press CtrlShift-i to open devtools-for-devtools, find the code that detects DOM storage changes, set a breakpoint. – woxxom Commented Mar 4, 2018 at 8:51
  • @wOxxOm That will probably not have the call stack that I wanted. – Derek 朕會功夫 Commented Mar 4, 2018 at 15:21
Add a comment  | 

1 Answer 1

Reset to default 25

Not on the native localStorage object, but on a proxied version:

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);
      };
    }
  })
});

We create a Proxy for window.localStorage that will intercept property assignment (handling the localStorage.someKey = someValue and localStorage["someKey"] = someValue cases) and property access (handling the localStorage.setItem("someKey", someValue) case).

Now we need to point window.localStorage at our proxy, but it's read-only. However, it's still configurable! We can redefine its value with Object.defineProperty.

发布评论

评论列表(0)

  1. 暂无评论