feat: 预览里的学生代码可以用 localStorage
Deploy / deploy (build, debian, 22) (push) Canceled after 0s

预览 iframe 没有 allow-same-origin,访问 localStorage 会抛异常。现在在学生代码之前
注入一个替身(支持常用方法、属性读写、Object.keys 等):

- 自己的编辑器(教程、挑战、自由创作):写入通过 postMessage 交给主页面,按“用户 + 任务”
  存到本站 localStorage 的 preview-storage:* 下,下次渲染注入回去,刷新后数据还在
- 看别人的作品:只存在内存里
- 单个任务最多 10 万字符,总共 50 万字符,超出时先删最久没用的,不挤占登录 token 的配额
- 下载的 index.html 不带替身

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-26 21:55:31 +08:00
1 parent dc91b9b5db
commit 40f3063b91
8 files changed
+230 -6

No files matched your search

+1
View File
@@ -90,6 +90,7 @@
:css="css"
:js="js"
:asset-base-url="assetBaseUrl"
persist-storage
show-code-button
clearable
@showCode="showCode = true"
+1
View File
@@ -80,6 +80,7 @@
:html="html"
:css="css"
:js="js"
persist-storage
show-code-button
clearable
@showCode="showCode = true"
+2 -1
View File
@@ -78,6 +78,7 @@
</template>
<script setup lang="ts">
import { storageShim } from "../utils/previewStorage"
import { onMounted, ref } from "vue"
import { useRouter } from "vue-router"
import { Icon } from "@iconify/vue"
@@ -91,7 +92,7 @@ const awards = ref<AwardSection[]>([])
function buildSrcdoc(item: ShowcaseItem): string {
const css = item.css ? `<style>${item.css}</style>` : ""
const js = item.js ? `<script>${item.js}<\/script>` : ""
return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="/normalize.min.css" />${css}</head><body>${item.html ?? ""}${js}</body></html>`
return `<!DOCTYPE html><html><head><meta charset="utf-8">${storageShim()}<meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="/normalize.min.css" />${css}</head><body>${item.html ?? ""}${js}</body></html>`
}
function openDetail(item: ShowcaseItem) {
+1
View File
@@ -14,6 +14,7 @@
:css="css"
:js="js"
:asset-base-url="assetBaseUrl"
persist-storage
/>
</template>
</n-split>