← Debugging Guides

阅读中文版本

DOMException SecurityError — localStorage Access Denied

Fix localStorage SecurityError by wrapping access for disabled cookies or sandboxed iframes and falling back to memory storage.

intermediatedebuggingbrowserstoragesecurity

Symptoms

  • DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document
  • Storage access throws in an iframe or third-party context
  • The error appears only for users blocking cookies

Possible causes

  • The browser blocks storage for the origin, often because cookies are disabled
  • Code runs in a sandboxed or cross-origin iframe without storage access
  • Access happens before a storage-access permission is granted

Diagnosis steps

Reproduce the access in a restricted context

try { window.localStorage.getItem('k'); } catch (e) { console.log(e.name); }

Interpretation

A SecurityError here confirms storage is blocked rather than the key being missing.

Detect availability safely

const ok = (() => { try { localStorage.setItem('_t', '1'); localStorage.removeItem('_t'); return true; } catch { return false; } })();

Interpretation

A feature-detection probe avoids throwing on every access and lets you fall back.

Root cause

Accessing window.localStorage throws SecurityError when the browser has disabled storage for the origin or document, such as with cookies blocked, sandboxed iframes, or blocked third-party storage. The throw occurs on property access, not on the value read.

Fix

Feature-detect storage once and wrap all access in a small adapter that falls back to an in-memory map, so the app keeps working when storage is unavailable.

Risk note

The in-memory fallback is not shared across tabs or reloads; do not rely on it for cross-session state.

Verify the fix

Run with cookies blocked or in a sandboxed iframe and confirm no uncaught error and the fallback engages.

Symptoms

The error “DOMException SecurityError — localStorage Access Denied” points at a specific failure mode. This guide documents the symptoms you can observe, the commands that isolate the cause, the root cause, the fix, and the checks that prove the fix works.

Observed symptoms include:

  • DOMException: Failed to read the ‘localStorage’ property from ‘Window’: Access is denied for this document
  • Storage access throws in an iframe or third-party context
  • The error appears only for users blocking cookies

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Reproduce the access in a restricted context

try { window.localStorage.getItem('k'); } catch (e) { console.log(e.name); }

A SecurityError here confirms storage is blocked rather than the key being missing.

Step 2: Detect availability safely

const ok = (() => { try { localStorage.setItem('_t', '1'); localStorage.removeItem('_t'); return true; } catch { return false; } })();

A feature-detection probe avoids throwing on every access and lets you fall back.

Likely contributors, in order of frequency:

  • The browser blocks storage for the origin, often because cookies are disabled
  • Code runs in a sandboxed or cross-origin iframe without storage access
  • Access happens before a storage-access permission is granted

Root Cause

Accessing window.localStorage throws SecurityError when the browser has disabled storage for the origin or document, such as with cookies blocked, sandboxed iframes, or blocked third-party storage. The throw occurs on property access, not on the value read.

The Fix

Feature-detect storage once and wrap all access in a small adapter that falls back to an in-memory map, so the app keeps working when storage is unavailable.

Watch out: The in-memory fallback is not shared across tabs or reloads; do not rely on it for cross-session state.

const storage = (() => {
  try {
    localStorage.setItem('__probe__', '1');
    localStorage.removeItem('__probe__');
    return localStorage;
  } catch {
    const mem = new Map();
    return {
      getItem: (k) => mem.get(k) ?? null,
      setItem: (k, v) => mem.set(k, String(v)),
      removeItem: (k) => mem.delete(k),
    };
  }
})();

Verify and Prevent

Run with cookies blocked or in a sandboxed iframe and confirm no uncaught error and the fallback engages.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.