跳转到内容

存储 · API

Clear-Site-Data 响应头

发布于

Clear-Site-Data 是一个 HTTP 响应头,指示浏览器删除该响应所属源的已存数据:Cookie、HTTP 缓存、DOM 存储与 Service Worker 注册,或者一次清掉全部类型。它相当于服务端替用户点了一次「清除站点数据」,也是退出登录时删除其他标签页里 localStorage 和 IndexedDB 的唯一标准手段。

Clear-Site-Data: "cache"
Clear-Site-Data: "cache", "cookies"
Clear-Site-Data: "cookies", "storage", "executionContexts"
Clear-Site-Data: "*"

每个指令都是带引号的字符串;不带引号的 Clear-Site-Data: cookies 无效并被忽略。该头只在 HTTPS(安全上下文)响应上生效,并且在响应 body 交给页面之前处理,因此页面响应上的 storage 指令会在该页面的脚本运行之前把存储清空。

指令 清除内容 支持情况(BCD http.headers.Clear-Site-Data)
"cache" 该源的 HTTP 缓存,视引擎还包括预渲染页面、bfcache 条目和脚本缓存。 Chrome 61、Firefox 63、Safari 17。Chrome 127+ 中部分请求在标签页重新加载前仍可能命中缓存(crbug 364634040)。
"cookies" 响应 URL 可注册域名下的全部 Cookie,含子域名,以及 HTTP 认证凭据。 Chrome 61、Firefox 63、Safari 17
"storage" 该源的 localStorage、sessionStorage、IndexedDB、Cache Storage、OPFS 与 Service Worker 注册。 Chrome 61、Firefox 63、Safari 17
"executionContexts" 清除后重新加载该源的所有浏览上下文。 仅 Firefox 63 至 68 与 Safari 17 至 18.3;Chromium 未实现。按不可用处理。
"prefetchCache"、"prerenderCache" 以该源为 referrer 的 Speculation Rules 预取与预渲染。 Chrome 138+。未标准化,Firefox 和 Safari 忽略。
"clientHints" 已存储的 Accept-CH 客户端提示偏好。"cache"、"cookies"、"*" 也会一并清除。 Chrome 117+
"*" 引擎支持的全部类型,含日后新增的类型。 Chrome 61、Firefox 63、Safari 17

"cookies" 指令作用于整个域:来自 app.example.com 的响应头同样会删除 example.com 和 www.example.com 的 Cookie。

该响应头本身自 Chrome 61、Firefox 63、Safari 17 起生效(BCD http.headers.Clear-Site-Data),MDN 将其列为 2023 年 9 月起的 Baseline。支持按指令区分,如「成员」表所示:三个核心指令各引擎都支持,预测缓存和客户端提示相关指令仅 Chromium 支持,"executionContexts" 没有正在发布的实现。纯 HTTP 和 Android WebView 中该头被忽略。

无。

响应头由服务端设置,所以示例是服务端代码,外加一个针对不支持该头的引擎的客户端兜底。

把头放在确认会话已结束的那个响应上,而不是放在提供退出按钮的页面上;浏览器在响应头到达的瞬间就会执行。

// Node.js / Express
app.post('/logout', (req, res) => {
req.session.destroy(() => {
res.set('Clear-Site-Data', '"cache", "cookies", "storage"');
res.status(204).end();
});
});

用 204 可以让响应很小并避免重定向,因为携带该头的重定向响应会在重定向请求发出之前就清除数据,顺带丢掉重定向目标可能需要的会话 Cookie。

一次有问题的部署后只清除 Service Worker 及其缓存

Section titled “一次有问题的部署后只清除 Service Worker 及其缓存”

"storage" 会连同 Cache Storage 一起移除 Service Worker 注册,是已发布的 worker 提供了损坏的应用壳时最快的恢复手段。从一个所有客户端都一定会请求的 URL(例如 manifest)上提供一次该头即可。

// Cloudflare Worker
export default {
async fetch(request) {
const response = await fetch(request);
if (new URL(request.url).pathname === '/manifest.webmanifest') {
const headers = new Headers(response.headers);
headers.set('Clear-Site-Data', '"storage"');
return new Response(response.body, { status: response.status, headers });
}
return response;
},
};

修复铺开之后要把头移除:它存在期间,每次抓取 manifest 都会注销 worker,应用会退化成普通网站。

脚本里没有任何信号能确认浏览器处理了该头。因此退出登录的处理函数也要自己清掉能清的东西并注销 Service Worker;在执行了该头的引擎上这是多余的,在没执行的引擎上这是唯一的清理。

async function confirmLogout() {
const res = await fetch('/logout', { method: 'POST' });
if (!res.ok) return false;
localStorage.clear();
sessionStorage.clear();
if (!('serviceWorker' in navigator)) {
return true; // 不支持 Service Worker:能清的只有 Web Storage
}
const regs = await navigator.serviceWorker.getRegistrations();
await Promise.all(regs.map((reg) => reg.unregister()));
return true;
}

document.cookie 无法删除 HttpOnly 的 Cookie,所以该头或服务端下发的过期 Set-Cookie 仍是去掉会话 Cookie 的唯一办法。

规范

规范状态
无。