You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React中可靠检测浏览器隐身模式?

可靠检测浏览器隐身模式的React自定义Hook方案

之前通过localStorage/sessionStorage检测的问题在于,像Firefox隐私浏览模式这类场景下,存储API是完全可用的,所以会出现误判。下面是几个适配多浏览器的可靠检测方案,结合React自定义Hook实现:

方案1:利用IndexedDB存储限制(适配Chromium系浏览器)

Chromium内核的浏览器(Chrome、Edge等)在隐身模式下,IndexedDB的存储空间被限制为0,尝试创建数据库会抛出错误。

import { useState, useEffect } from 'react';

const useIncognitoDetector = () => {
  const [isIncognito, setIsIncognito] = useState(null);

  useEffect(() => {
    const checkIncognito = async () => {
      try {
        // 尝试创建IndexedDB测试数据库
        const request = indexedDB.open('IncognitoTestDB');
        await new Promise((resolve, reject) => {
          request.onupgradeneeded = resolve;
          request.onerror = reject;
          request.onsuccess = resolve;
        });
        // 能正常创建则不是隐身模式
        setIsIncognito(false);
        // 清理测试数据库
        indexedDB.deleteDatabase('IncognitoTestDB');
      } catch (e) {
        // 创建失败则判定为隐身模式
        setIsIncognito(true);
      }
    };

    checkIncognito();
  }, []);

  return isIncognito;
};

export default useIncognitoDetector;

方案2:FileSystem API检测(适配Safari)

Safari的隐身模式下无法通过FileSystem API获取可写的文件系统,会直接拒绝请求。

import { useState, useEffect } from 'react';

const useIncognitoDetector = () => {
  const [isIncognito, setIsIncognito] = useState(null);

  useEffect(() => {
    const checkIncognito = async () => {
      if (!window.showOpenFilePicker) {
        // 不支持该API的浏览器,降级为非隐身判定
        setIsIncognito(false);
        return;
      }
      try {
        // 尝试请求文件系统访问权限
        await window.showOpenFilePicker({ type: [] });
        setIsIncognito(false);
      } catch (e) {
        // Safari隐身模式下会抛出NotAllowedError
        if (e.name === 'NotAllowedError') {
          setIsIncognito(true);
        } else {
          setIsIncognito(false);
        }
      }
    };

    checkIncognito();
  }, []);

  return isIncognito;
};

export default useIncognitoDetector;

方案3:多方法综合检测(全局兼容)

结合多种检测手段,覆盖不同浏览器的行为差异,提升检测准确率:

import { useState, useEffect } from 'react';

const useIncognitoDetector = () => {
  const [isIncognito, setIsIncognito] = useState(null);

  useEffect(() => {
    const checkIncognito = async () => {
      let result = false;

      // 第一步:检测Chromium系IndexedDB限制
      try {
        const request = indexedDB.open('IncognitoTestDB');
        await new Promise((resolve, reject) => {
          request.onupgradeneeded = resolve;
          request.onerror = reject;
          request.onsuccess = resolve;
        });
        indexedDB.deleteDatabase('IncognitoTestDB');
      } catch (e) {
        result = true;
      }

      // 第二步:检测Safari FileSystem限制(若第一步未判定为隐身)
      if (!result && window.showOpenFilePicker) {
        try {
          await window.showOpenFilePicker({ type: [] });
        } catch (e) {
          if (e.name === 'NotAllowedError') {
            result = true;
          }
        }
      }

      // 第三步:降级检测localStorage(仅作为补充)
      if (!result) {
        try {
          localStorage.setItem('test_incognito', 'test');
          localStorage.removeItem('test_incognito');
        } catch (e) {
          result = true;
        }
      }

      setIsIncognito(result);
    };

    checkIncognito();
  }, []);

  return isIncognito;
};

export default useIncognitoDetector;

使用说明

在React组件中直接调用Hook即可:

function App() {
  const isIncognito = useIncognitoDetector();

  return (
    <div>
      {isIncognito === null ? '检测中...' : isIncognito ? '当前处于隐身模式' : '当前未处于隐身模式'}
    </div>
  );
}

注意:所有检测方法都无法做到100%精准(浏览器厂商可能随时修改隐私模式的行为),但综合检测能覆盖绝大多数主流浏览器的场景。

内容的提问来源于stack exchange,提问作者Richardson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:43:12