问题:如果我想使用js来判断当前的浏览器是32位还是64位,我该怎么办?有没有靠谱的方法?
为什么会有这个需求呢?因为在执行js任务时,对内存会有一定的要求。如果内存大于512M~1.5GB,那么会很容易出现“内存不足的错误”为什么会有这个需求呢?因为在执行js任务时,对内存会有一定的要求。如果内存大于512M~1.5GB,那么会很容易出现“内存不足的错误”
对于64位浏览器,"Out of Memory" 很少出现;但是在32位的浏览器,出现的很频繁。 那么,就需要在执行JS前,判断一下,当前浏览器是32位的还是64位的。如果是32位的,提示用户可能会遇到的一些问题,并建议升级为64版本。
测试方法1:
检查navigator.userAgent
和 navigator.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();