Back

JavaScript 中生成 UUID 的实用指南

JavaScript 中生成 UUID 的实用指南

简介

需要为你的 JavaScript 应用程序生成唯一标识符吗?无论你是在构建数据库驱动的应用、管理用户会话,还是跟踪分布式请求,UUID 生成都是每个开发者需要掌握的基本技能。

本指南涵盖了 JavaScript UUID 生成的现代方法,从内置的 crypto.randomUUID() 方法到功能全面的 uuid npm 包。你将学会如何根据具体使用场景选择合适的方法——无论是前沿的 Web 应用、Node.js 服务,还是需要广泛兼容性的传统系统。

核心要点

  • 在现代环境中使用 crypto.randomUUID()(Node.js 14.17+ 和最新浏览器)
  • 对于需要加密安全性的传统浏览器支持,实现 crypto.getRandomValues()
  • 当需要特定 UUID 版本或最大兼容性时,选择 uuid npm 包
  • 由于缺乏加密安全性,切勿在生产环境中使用 Math.random() 生成 UUID

什么是 UUID,为什么要使用它?

UUID(通用唯一标识符)是一个 128 位标识符,格式为 36 个字符:550e8400-e29b-41d4-a716-446655440000。这些标识符也被称为 GUID,实际上可以保证在不需要中央授权机构或数据库协调的情况下具有唯一性。

对于前端和 Node.js 开发者来说,UUID 解决了以下关键问题:

  • 数据库记录:生成主键而无需担心自增冲突
  • 会话令牌:创建不可预测的唯一会话标识符
  • 文件命名:防止上传内容的命名冲突
  • 请求跟踪:跨微服务追踪操作

现代方法:crypto.randomUUID()

crypto.randomUUID() 方法是当前在现代环境中生成唯一 ID 值的标准方法。它内置于浏览器和 Node.js(14.17+)中,无需依赖项,并生成加密安全的 UUID v4 值。

浏览器实现

const uuid = crypto.randomUUID();
console.log(uuid); // "3b99e3e0-7598-4bf8-b9c1-e915af91713c"

Node.js 实现

import { randomUUID } from 'crypto';

const uuid = randomUUID();
console.log(uuid); // "b7e44f0a-811f-4c1c-b7f0-48d51f5dbc1f"

浏览器支持:Chrome 92+、Firefox 95+、Safari 15.4+、Edge 92+
Node.js 支持:14.17.0+ 版本

当你需要在现代应用程序中生成安全的随机 UUID 而不依赖外部库时,使用 crypto.randomUUID()

备用方法:crypto.getRandomValues()

对于不支持 crypto.randomUUID() 的环境,你可以使用 crypto.getRandomValues() 实现 UUID v4 生成。此方法适用于早至 Chrome 11 的浏览器以及带有 crypto 模块的 Node.js 版本。

function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = crypto.getRandomValues(new Uint8Array(1))[0];
    const v = c === 'x' ? (r & 0x0f) : ((r & 0x03) | 0x08);
    return v.toString(16);
  });
}

const uuid = generateUUID();
console.log(uuid); // "42254574-affd-47cc-9915-0ecae592351b"

这种方法在支持旧环境的同时保持了加密安全性。

uuid npm 包提供最大灵活性

uuid npm 包仍然是 JavaScript UUID 生成最通用的解决方案,特别是当你需要特定的 UUID 版本或最大兼容性时。

安装

npm install uuid

基本用法(UUID v4)

import { v4 as uuidv4 } from 'uuid';

const uuid = uuidv4();
console.log(uuid); // "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"

其他 UUID 版本

import { v1, v3, v5 } from 'uuid';

// v1:基于时间戳(可排序)
const uuid1 = v1(); 

// v3/v5:基于名称(确定性)
const uuid5 = v5('hello.example.com', v5.DNS);

uuid 包支持所有 UUID 版本(v1-v5),在以下情况下特别适用:

  • 需要可排序标识符的基于时间戳的 UUID(v1)
  • 从命名空间/名称对生成确定性 UUID(v3、v5)
  • 与旧版本 Node.js 的向后兼容性
  • React Native 或其他非标准环境

何时避免使用 Math.random()

虽然你可能会发现使用 Math.random() 的 UUID 实现,但这些实现应该仅用于测试或非安全上下文:

// ⚠️ 不安全 - 仅用于测试
function testUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

Math.random() 缺乏加密安全性,不应用于生产环境的 UUID。

最佳实践和验证

UUID 验证

始终验证来自外部来源的 UUID:

function isValidUUID(uuid) {
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
  return uuidRegex.test(uuid);
}

console.log(isValidUUID('550e8400-e29b-41d4-a716-446655440000')); // true

选择正确的方法

  • 现代 Web 应用或 Node.js 14.17+:使用 crypto.randomUUID()
  • 需要传统浏览器支持:使用 crypto.getRandomValues() 实现
  • 需要特定 UUID 版本(v1、v3、v5):使用 uuid npm 包
  • 最大兼容性:使用 uuid npm 包
  • 仅用于快速测试/原型:Math.random() 实现

结论

在 JavaScript 中生成 UUID 并不复杂。对于大多数现代应用程序,crypto.randomUUID() 提供了简单、安全的解决方案。当你需要更广泛的兼容性或特定的 UUID 版本时,uuid npm 包可以满足你的需求。只需记住避免在生产环境中使用 Math.random(),并验证来自外部来源的任何 UUID。

选择与你的环境和需求相匹配的方法——未来的你(以及你的团队)会感谢你在整个代码库中使用了简洁、可靠的唯一标识符。

常见问题

UUID v4 使用随机或伪随机数,使每个 ID 不可预测。UUID v5 使用 SHA-1 哈希从命名空间和名称生成确定性 ID,因此相同的输入始终产生相同的 UUID。

不可以,React Native 原生不支持 crypto.randomUUID()。请改用 uuid npm 包,它提供了在 React Native 环境中兼容的实现。

对于较短的 ID,可以考虑使用 nanoid 或 shortid 包。它们生成 URL 安全的唯一字符串,比 UUID 更紧凑,同时对大多数应用程序保持足够的唯一性。

是的,UUID v4 值是加密随机的,可以安全暴露。但是,避免在公共场合使用 UUID v1,因为它包含时间戳和 MAC 地址信息,可能会泄露系统详细信息。

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay