JavaScript 生成 UUID 的常见方案与避坑指南
在前后端分离的架构下,UUID(通用唯一识别码)在前端的应用场景越来越广泛。除了传统的后端主键生成,前端现在也常需要处理离线数据同步、本地缓存 Key、埋点上报以及 WebSocket 消息去重等任务。虽然 Java 有 java.util.UUID,但 JavaScript 生态相对分散,实现方式五花八门。作为开发者,我们需要清楚不同方案的优缺点,避免在生产环境踩坑。
为什么前端需要生成 UUID?
常见的场景包括:
- 离线编辑:用户无网时本地保存草稿,联网后同步,需要临时 ID 标识数据。
- 埋点上报:追踪用户行为事件,需要唯一标识符区分请求。
- 表单自动保存:刷新页面不丢失数据,需通过 ID 关联草稿版本。
- WebSocket 去重:网络抖动导致消息重复发送,需通过 ID 判断是否已处理。
UUID 基础概念
UUID 标准格式为 8-4-4-4-12 的 32 位十六进制数字,例如 550e8400-e29b-41d4-a716-446655440000。前端常用的是 v4 版本,基于纯随机数生成,格式类似 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx。v1 版本依赖时间戳和 MAC 地址,但在浏览器环境中获取 MAC 地址受限,因此 v4 是主流选择。
方案一:Math.random() 伪随机
这是最基础的写法,利用正则替换生成字符串:
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0;
var v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
console.log(generateUUID());
这种写法看似简洁,实则隐患巨大。Math.random() 是伪随机算法,种子机制在不同浏览器和低端安卓机上表现不一致。曾有案例显示,特定国产千元机因随机数生成器缺陷,短时间内产生大量重复 UUID。此外,它不具备加密安全性,若用于会话令牌可能被预测。仅建议用于非关键的前端临时缓存 Key。
方案二:时间戳 + 随机数组合
为了增加唯一性,有人尝试加入时间戳:
() {
id = ;
timestamp = .().();
randomPart = .().().(, );
id = ;
id;
}


