无Storage Access API支持时,如何将旧域名的LocalStorage数据迁移至新域名?
无Storage Access API支持时,如何将旧域名的LocalStorage数据迁移至新域名?
我之前把网站托管在GitHub Pages上,用的是默认域名(比如auroratide.github.io/my-website),现在想迁移到自定义域名(比如my-website.com)。但棘手的是,新域名没法直接访问旧域名存在LocalStorage里的数据,用户会突然丢失之前保存的所有内容,得想办法把这些数据迁移过来。
一开始我自认为想到了个聪明办法:做了另一个GitHub Pages站点auroratide.github.io/storage-migration,打算让新域名把这个站点嵌成iframe,然后通过postMessage把旧数据传给父窗口。结果发现完全行不通——因为浏览器的状态分区机制,嵌入的iframe没法访问自己的LocalStorage,简单说就是存储数据会同时按顶级域名和嵌入域名双重标记,iframe里的站点根本拿不到原来旧域名下存的内容。
后来我又尝试用存储访问API让iframe请求权限,这在Chrome里能用,但其他所有浏览器都不支持,我居然没先查兼容性就写完了整个方案,现在想想真的太草率了。
现在我想问:没有存储访问API的支持,还有办法把旧域名的LocalStorage数据迁移到新域名吗? 虽然这个问题这些年被问过很多次,但我实在分不清哪些是过时的老方法,哪些是现在还能生效的新方案。
附上我现在在iframe站点里用的代码,说不定能帮大家理解我的思路:
function postMessage(payload) { parent.postMessage(payload, NEW_DOMAIN) } function transferStorage(storage) { postMessage(Object.entries(storage)) } async function hasStorageAccess() { if (!document.requestStorageAccess) return true if (await document.hasStorageAccess()) return true try { const permission = await navigator.permissions.query({ name: "storage-access" }) if (permission.state === "granted") { await document.requestStorageAccess() return true } else if (permission.state === "prompt") { return false } else if (permission.state === "denied") { return false } } catch (error) { console.warn(error) return false } return false } async function manuallyTransfer() { /* Imagine code here that toggles button and loader visibilities */ const hasAccess = await hasStorageAccess() if (!hasAccess) { try { await document.requestStorageAccess() } catch (error) { postMessage("failed") return } } const handle = await document.requestStorageAccess({ localStorage: true }) transferStorage(handle.localStorage) } async function automaticallyTransfer() { const hasAccess = await hasStorageAccess() if (hasAccess) { if (document.requestStorageAccess) { const handle = await document.requestStorageAccess({ localStorage: true }) transferStorage(handle.localStorage) } else { transferStorage(localStorage) } } else { console.log("Requires manual input to migrate data.") const button = document.querySelector("#transfer-button") button.addEventListener("click", manuallyTransfer) button.removeAttribute("hidden") postMessage("manual") } } if (parent != null) { automaticallyTransfer() }
备注:内容来源于stack exchange,提问作者Auroratide
相关产品推荐
相关产品推荐

