← 中文资源

简体中文版本

存储分区

存储分区按顶层站点切分 Cookie、缓存与存储:被嵌入的第三方框架在两个站点中看到两个独立存储罐,无法再跨站共享身份。

阅读英文原文

概念定义

历史上,可嵌入的源无论在哪里加载都携带同一个存储罐——这正是跨站追踪所需要的。分区把键从“源”改为“源加顶层站点”,同一 iframe 在两个发布商那里对自家后端就是两个不同客户端。

工作机制

浏览器按顶层站点分区 HTTP 缓存、存储 API 与 service worker。Storage Access API 允许被嵌入框架在策略允许处经用户中介请求非分区 Cookie 访问;Related Website Sets 为有限的同属站点组提供合法跨域流。

使用场景

嵌入式登录与身份小组件、支付提供商、按站点授权的视频平台、共享 CDN 的缓存命中经济。迁移方向是通过 postMessage 契约把会话委托给第一方存储,或顶层重定向。

常见误区

破坏是静默的:嵌入方看到的是空存储而不是报错,表象像“莫名登出”。缓存分区会降低跨站缓存复用、抬高 CDN 请求量。测试矩阵必须覆盖嵌入上下文,而不仅是顶层浏览。

代码示例

const COMMON_PATTERNS = [/^123456/, /password/i, /qwerty/i, /(.)\1{2,}/];

// Password strength estimation based on character-pool entropy.
export function estimatePasswordStrength(password) {
  const value = String(password);
  const pools = [
    [/[a-z]/, 26],
    [/[A-Z]/, 26],
    [/[0-9]/, 10],
    [/[^A-Za-z0-9]/, 33],
  ];
  const poolSize = pools.reduce((total, [pattern, size]) => {
    return total + (pattern.test(value) ? size : 0);
  }, 0);
  const unique = new Set(value).size;
  const effectiveLength = Math.max(unique, Math.ceil(value.length * 0.75));
  let entropyBits = poolSize > 0 ? effectiveLength * Math.log2(poolSize) : 0;
  for (const pattern of COMMON_PATTERNS) {
    if (pattern.test(value)) entropyBits *= 0.5;
  }
  if (value.length < 8) entropyBits *= 0.6;
  const thresholds = [20, 40, 60, 80];
  let score = thresholds.filter((threshold) => entropyBits >= threshold).length;
  if (value.length === 0) score = 0;
  const labels = ["very weak", "weak", "fair", "strong", "very strong"];
  return {
    entropyBits: Math.round(entropyBits),
    score,
    label: labels[score],
    poolSize,
    length: value.length,
    uniqueCharacters: unique,
  };
}