cookie-tools.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*const COOKIE_EXPIRES_DAYS = 7;
  2. export const getNativeCookie = (name: string): string | null => {
  3. if (typeof document === "undefined") return null;
  4. const cookies = document.cookie.split("; ").map((c) => c.trim());
  5. const found = cookies.find((c) => c.startsWith(name + "="));
  6. return found ? decodeURIComponent(found.split("=")[1]) : null;
  7. };
  8. export const getCookie = (name: string): string | null => {
  9. if (typeof document === "undefined") return null;
  10. const match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
  11. return match ? decodeURIComponent(match[2]) : null;
  12. };
  13. export const setCookie = (
  14. name: string,
  15. value: string | number,
  16. { days = COOKIE_EXPIRES_DAYS, isEncode = false }: { days?: number; isEncode?: boolean } = {}
  17. ) => {
  18. if (typeof document === "undefined") return;
  19. const d = new Date();
  20. d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
  21. // const expires = new Date(Date.now() + days * 864e5).toUTCString();
  22. const expires = d.toUTCString();
  23. const val = isEncode ? encodeURIComponent(String(value)) : value;
  24. document.cookie = `${name}=${val}; expires=${expires}; path=/`;
  25. };
  26. export const deleteCookie = (name: string) => {
  27. if (typeof document === "undefined") return;
  28. document.cookie = `${name}=; Max-Age=0; path=/`;
  29. };
  30. */
  31. import {GUEST_COOKIE_OPTION} from "@/utils/constants";
  32. // cookie.ts
  33. export interface CookieOptions {
  34. /** 过期天数(从当前时间起算),默认 7 天 */
  35. maxAge?: number;
  36. /** 是否需要对值进行编码(encodeURIComponent),默认 false */
  37. encode?: boolean;
  38. /** Cookie 路径,默认 '/' */
  39. path?: string;
  40. /** Cookie 域名 */
  41. domain?: string;
  42. /** 是否仅 HTTPS 传输 */
  43. secure?: boolean;
  44. /** SameSite 属性 */
  45. sameSite?: 'Strict' | 'Lax' | 'None';
  46. }
  47. // 对正则特殊字符进行转义,避免名称中的特殊字符导致匹配错误
  48. function escapeRegExp(string: string): string {
  49. return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  50. }
  51. /**
  52. * 获取指定名称的 cookie 值
  53. * 解决了值中包含等号的问题,并对名称中的正则特殊字符做了转义
  54. */
  55. export function getCookie(name: string): string | null {
  56. if (typeof document === 'undefined') return null;
  57. const escapedName = escapeRegExp(name);
  58. // 在 document.cookie 开头或分号后的空格之后匹配名称,值部分匹配到下一个分号或结束
  59. const regex = new RegExp(`(?:^|;\\s*)${escapedName}=([^;]*)`);
  60. const match = document.cookie.match(regex);
  61. return match ? decodeURIComponent(match[1]) : null;
  62. }
  63. /**
  64. * 设置 cookie
  65. * 默认对值进行编码以保证安全存储,可通过 options.encode = false 关闭
  66. */
  67. export function setCookie(
  68. name: string,
  69. value: string | number | boolean,
  70. options: CookieOptions = {}
  71. ): void {
  72. if (typeof document === 'undefined') return;
  73. const setOption = Object.assign({},GUEST_COOKIE_OPTION,options);
  74. const {
  75. maxAge,
  76. encode, // 默认编码,更加安全
  77. path,
  78. domain,
  79. secure,
  80. sameSite,
  81. } = setOption;
  82. // 处理过期时间
  83. const expires = new Date(Date.now() + maxAge * 1000).toUTCString();
  84. // 处理值:编码或直接转换
  85. const val = encode
  86. ? encodeURIComponent(String(value))
  87. : String(value);
  88. // 构建 cookie 字符串
  89. let cookie = `${name}=${val}; expires=${expires}; path=${path}`;
  90. if (domain) cookie += `; domain=${domain}`;
  91. if (secure) cookie += '; secure';
  92. if (sameSite) cookie += `; samesite=${sameSite}`;
  93. document.cookie = cookie;
  94. }
  95. /**
  96. * 删除指定名称的 cookie
  97. * 通过设置 Max-Age=0 并匹配 path/domain 等属性来确保删除
  98. */
  99. export function deleteCookie(
  100. name: string,
  101. options: Pick<CookieOptions, 'path' | 'domain' | 'secure'> = {}
  102. ): void {
  103. if (typeof document === 'undefined') return;
  104. const {
  105. path: defaultPath,
  106. secure: defaultSecure
  107. } = GUEST_COOKIE_OPTION;
  108. const { domain } = options;
  109. const path = options.path || defaultPath;
  110. const secure = options.secure || defaultSecure;
  111. // 若删除时指定了 domain 或 secure,需要与设置时一致才能删除成功
  112. let cookie = `${name}=; Max-Age=0; path=${path}`;
  113. if (domain) cookie += `; domain=${domain}`;
  114. if (secure) cookie += '; secure';
  115. document.cookie = cookie;
  116. }