* docs: improve deployment troubleshooting docs * docs: fix GitHub casing in FAQ * docs: clarify subdomain address creation
7.2 KiB
Cloudflare Pages 前端
<script setup> import { ref } from 'vue' import JSZip from 'jszip'; const domain = ref("") const downloadUrl = ref("") const tip = ref("下载") const errorMessage = ref("") const resetDownloadUrl = () => { if (!downloadUrl.value) { return } window.URL.revokeObjectURL(downloadUrl.value) downloadUrl.value = "" } const validateDomain = (value) => { const normalizedValue = value.trim() if (!normalizedValue) { return "请输入以 https:// 开头的后端 API 地址" } if (/\s/.test(normalizedValue)) { return "后端 API 地址不能包含空白字符" } if (!normalizedValue.startsWith("https://")) { return "后端 API 地址必须以 https:// 开头" } if (normalizedValue.endsWith("/")) { return "后端 API 地址末尾不要带 /" } try { const url = new URL(normalizedValue) if (url.protocol !== "https:") { return "后端 API 地址必须以 https:// 开头" } if (url.pathname !== "/" || url.search || url.hash) { return "请填写后端 API 根地址,不要带路径、参数或锚点" } } catch { return "后端 API 地址格式不正确" } return "" } const generate = async () => { const normalizedDomain = domain.value.trim() const validationError = validateDomain(normalizedDomain) errorMessage.value = validationError resetDownloadUrl() if (validationError) { return } domain.value = normalizedDomain let timeoutId = 0 try { const controller = new AbortController() timeoutId = window.setTimeout(() => controller.abort(), 10000) const response = await fetch("/ui_install/frontend.zip", { signal: controller.signal }); if (!response.ok) { errorMessage.value = "下载前端压缩包失败,请稍后重试" return } const arrayBuffer = await response.arrayBuffer(); var zip = new JSZip(); await zip.loadAsync(arrayBuffer); let target_path = "" const directory = zip.folder("assets"); if (directory) { for (const [relativePath, zipEntry] of Object.entries(directory.files)) { console.log(relativePath); if (relativePath.startsWith("assets/index-") && relativePath.endsWith(".js")){ let content = await zipEntry.async("string"); content = content.replaceAll("https://temp-email-api.xxx.xxx", normalizedDomain); target_path = relativePath; zip.file(relativePath, content); break; } } } if (!target_path) { errorMessage.value = "没有找到前端入口文件,生成失败" return } const blob = await zip.generateAsync({ type: "blob" }); const url = window.URL.createObjectURL(blob); errorMessage.value = "" downloadUrl.value = url; } catch (error) { console.error("Error: ", error); if (error instanceof DOMException && error.name === "AbortError") { errorMessage.value = "下载超时,请刷新页面后重试" return } errorMessage.value = "生成失败,请刷新页面后重试" } finally { window.clearTimeout(timeoutId) } } </script>-
点击
Compute (Workers)->Workers & Pages->Create -
选择
Pages,选择Use direct upload -
输入部署的 worker 地址,必须填写后端 API 根地址,并且以
https://开头,地址不要带/,点击生成,成功会出现下载按钮,你会得到一个 zip 包- 此处 worker 域名为后端 api 的域名,比如我部署在
https://temp-email-api.awsl.uk,则填写https://temp-email-api.awsl.uk - 如果你的域名是
https://temp-email-api.xxx.workers.dev,则填写https://temp-email-api.xxx.workers.dev - 不要填写前端
Pages自己的域名,也不要带/admin、/api等路径,否则前端请求会打到错误地址,可能出现Cannot read properties of undefined (reading 'map')或405 Method Not Allowed - 填写前请先在浏览器打开
https://你的worker域名/open_api/settings,确认返回 JSON;如果返回 HTML、404、405 或 Cloudflare 挑战页,请先修复 Worker 绑定、变量或安全策略
[!warning] 注意
worker.dev域名在中国无法访问,请自定义域名不要给后端 API 域名开启 Under Attack、Bot Fight、Managed Challenge 等会返回浏览器挑战页的安全策略。前端 XHR 请求无法完成这些挑战,常见表现是
Network Error。生成 {{ tip }}示例:`https://temp-email-api.example.com`,不要填写前端 Pages 域名,也不要带结尾 `/`。
{{ errorMessage }}
Note
你也可以手动部署,从这里下载 zip, frontend.zip
修改压缩包里面的 index-xxx.js 文件 ,xx 是随机的字符串
搜索
https://temp-email-api.xxx.xxx,替换成你 worker 的后端 API 根地址,然后部署新的 zip 文件。如果填成前端 Pages 域名,常见现象就是页面报map错误或接口返回405如果第一次填错后重新部署仍然报错,请用无痕窗口测试或清理浏览器缓存,避免浏览器继续使用旧的前端资源。
- 此处 worker 域名为后端 api 的域名,比如我部署在
-
选择
Pages,点击Create Pages, 修改名称,上传下载的 zip 包[!warning] 重要:SPA 模式 本项目是单页应用(SPA),必须在部署时展开高级选项,将「未找到处理」设置为
Single-page application (SPA)。 否则刷新页面或直接访问/admin等子路径时会返回 404。然后点击
Deploy -
打开 刚刚部署的
Pages,点击Custom Domain这里可以添加自己的域名,你也可以使用自动生成的*.pages.dev的域名。能打开域名说明部署成功。




