如何鉴别浏览器位数...


问题:如果我想使用js来判断当前的浏览器是32位还是64位,我该怎么办?有没有靠谱的方法?

为什么会有这个需求呢?因为在执行js任务时,对内存会有一定的要求。如果内存大于512M~1.5GB,那么会很容易出现“内存不足的错误”为什么会有这个需求呢?因为在执行js任务时,对内存会有一定的要求。如果内存大于512M~1.5GB,那么会很容易出现“内存不足的错误”

对于64位浏览器,"Out of Memory" 很少出现;但是在32位的浏览器,出现的很频繁。 那么,就需要在执行JS前,判断一下,当前浏览器是32位的还是64位的。如果是32位的,提示用户可能会遇到的一些问题,并建议升级为64版本。

测试方法1:

检查navigator.userAgentnavigator.platform

function is64Bit() {
  const platform = navigator.platform.toLowerCase();
  const userAgent = navigator.userAgent.toLowerCase();

  // 常见平台判断
  if (platform.includes('win64') || platform.includes('x64') ||
      userAgent.includes('win64') || userAgent.includes('x64') ||
      userAgent.includes('amd64') || userAgent.includes('x86_64') ||
      userAgent.includes('wow64')) {
    return true; // 64位
  }

  return false; // 默认认为是32位
}

console.log(is64Bit() ? "64位环境" : "32位环境");

显示的不对!!!!

其实,userAgent中显示x64/Win64是“模拟了64位环境”或“报告为64位系统”。但重点不是模拟,而是js就是运行在64位系统上,但浏览器本身是32位进程。举个简单的例子: 操作系统是 64 位 → 地是 64 位

  • 浏览器是 32 位 → 你开了一辆只能走小路(最多 2GB 内存)的车
  • userAgent 报告说:“我在 64 位的地上跑”——这是真的
  • 但你开的车仍然是“32 位”的,不管地多宽你也开不快、跑不远

测试方法2:

使用c++,编译为wasm 是否可行?

#include <iostream>

int main() {
    if (sizeof(void*) == 8) {
        std::cout << "64-bit" << std::endl;
    } else if (sizeof(void*) == 4) {
        std::cout << "32-bit" << std::endl;
    } else {
        std::cout << "Unknown pointer size" << std::endl;
    }
    return 0;
}

将上面的代码编译为wasm,在浏览器环境中运行,结果还是64-bit

测试方法3:

在网页打开时,我通过js的网络请求或使用window.open,打开下面的页面“chrome://version”。通过页面反馈的结果,分析浏览器版本。如果能拿到结果,那么肯定能判断出是32位还是64位。

但是,愿望是美好的,结局是残酷的o(╥﹏╥)o

协议"chrome://" 在发布环境中是禁止访问的!!! 此路不通。

终极方案

捕获浏览器异常,如果发现"out of Memory",就进行友善提示。但是:捕获“浏览器整个崩溃 / 标签页崩溃”是前端 JavaScript 本身无法直接完成的,因为:一旦标签页崩溃(Renderer Process 崩溃)或整个浏览器崩溃,JavaScript 不再执行,页面上下文丢失,你没有办法在当时感知它。但我们可以通过 间接手段 构建一个 “崩溃检测机制”,在 页面重新打开或恢复时检测是否为异常关闭或崩溃恢复。这是个折中的方案,靠谱可用。

const TAB_ID = Date.now().toString() + Math.random().toString(36).substr(2, 5);
const ALIVE_KEY = `tab_alive_${TAB_ID}`;
const HEARTBEAT_KEY = `tab_heartbeat_${TAB_ID}`;
const HEARTBEAT_INTERVAL = 3000; // 每 3 秒心跳一次
const MAX_HEARTBEAT_DELAY = 10000; // 超过 10 秒没心跳,认为异常关闭

function setHeartbeat() {
  localStorage.setItem(HEARTBEAT_KEY, Date.now().toString());
}

// 心跳定时器
const heartbeatTimer = setInterval(setHeartbeat, HEARTBEAT_INTERVAL);

// 启动时标记为“活跃”
localStorage.setItem(ALIVE_KEY, '1');
setHeartbeat();

// 正常关闭时清除状态
function clearStatus() {
  localStorage.removeItem(ALIVE_KEY);
  localStorage.removeItem(HEARTBEAT_KEY);
}
window.addEventListener('beforeunload', clearStatus);
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    clearStatus();
  }
});

// 加载时检测是否有未清除的状态(崩溃后重开)
function detectCrash() {
  const tabs = Object.keys(localStorage).filter(k => k.startsWith('tab_alive_'));
  tabs.forEach(aliveKey => {
    const id = aliveKey.replace('tab_alive_', '');
    const heartbeatKey = `tab_heartbeat_${id}`;
    const lastHeartbeat = parseInt(localStorage.getItem(heartbeatKey) || '0');

    const now = Date.now();
    if (now - lastHeartbeat > MAX_HEARTBEAT_DELAY) {
      console.warn(`检测到标签页崩溃或非正常关闭(ID: ${id})`);

      // 上报异常日志(可替换为自己的上报逻辑)
      reportCrash(id, lastHeartbeat);

      // 清理旧数据
      localStorage.removeItem(aliveKey);
      localStorage.removeItem(heartbeatKey);
    }
  });
}

// 模拟崩溃上报逻辑
function reportCrash(tabId, lastSeen) {
  console.log(`检测到您上次程序异常退出,可能是内存不足引起的页面崩溃,建议您更新为64位浏览器`);
}

detectCrash();
原则是:只要不是自己手动关闭(正常退出),都进行崩溃提示。

综上所述:没有靠谱的方法来解决js运行环境判断的问题,只有折中的方案。