mirror of
https://github.com/mintlify/docs.git
synced 2026-09-14 13:35:46 +08:00
93f848e73d
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com> Co-authored-by: Ethan Palm <56270045+ethanpalm@users.noreply.github.com>
214 lines
8.4 KiB
Plaintext
214 lines
8.4 KiB
Plaintext
---
|
||
title: "使用 Cloudflare Workers 在子路径下部署"
|
||
sidebarTitle: "Cloudflare"
|
||
description: "通过 Cloudflare Workers 将你的 Mintlify 文档部署到域名的子路径,包含分步设置和 DNS 配置说明。"
|
||
keywords: ["Cloudflare Workers", "子路径路由", "反向代理设置", "Worker 配置"]
|
||
boost: 3
|
||
---
|
||
|
||
import Propagating from "/snippets/zh/custom-subpath-propagating.mdx";
|
||
import SubpathSetupSteps from "/snippets/zh/subpath-setup-steps.mdx";
|
||
|
||
要使用 Cloudflare 将文档托管在诸如 `yoursite.com/docs` 这样的子路径下,你必须创建并配置一个 Cloudflare Worker。
|
||
|
||
<Info>
|
||
在开始之前,你需要一个 Cloudflare 账号和一个域名(可以在 Cloudflare 内或外进行管理)。
|
||
</Info>
|
||
|
||
<div id="set-your-base-path">
|
||
## 设置你的基础路径
|
||
</div>
|
||
|
||
<SubpathSetupSteps />
|
||
|
||
控制台会显示一个已填入你的子域、域名和基础路径的 Cloudflare Worker 脚本。请在 [配置路由](#configure-routing) 步骤中使用该脚本,而不必手动替换示例脚本中的占位值。
|
||
|
||
<div id="set-up-a-worker">
|
||
## 设置 Worker
|
||
</div>
|
||
|
||
如果你尚未创建,请按照 [Cloudflare Workers 入门指南](https://developers.cloudflare.com/workers/get-started/dashboard/)创建一个 Cloudflare Worker。
|
||
|
||
<Tip>
|
||
如果你的 DNS 提供商是 Cloudflare,请为该 CNAME 记录关闭代理,以避免潜在的配置问题。
|
||
</Tip>
|
||
|
||
<div id="proxies-with-vercel-deployments">
|
||
### 使用 Vercel 部署时的代理
|
||
</div>
|
||
|
||
如果你在 Vercel 部署中使用 Cloudflare 作为代理,必须确保配置正确,以避免与 Vercel 的 domain 验证和 SSL 证书签发发生冲突。
|
||
|
||
错误的代理配置可能会阻止 Vercel 为 Let's Encrypt SSL 证书进行签发,并导致 domain 验证失败。
|
||
|
||
<div id="required-path-allowlist">
|
||
#### 必需的路径白名单
|
||
</div>
|
||
|
||
你的 Cloudflare Worker 必须允许以下特定路径的流量通过,且不能阻止或重定向:
|
||
|
||
- `/.well-known/acme-challenge/*` - 用于 Let's Encrypt 证书验证,必需
|
||
- `/.well-known/vercel/*` - 用于 Vercel domain 验证,必需
|
||
|
||
虽然 Cloudflare 会自动处理许多验证规则,但创建额外的自定义规则可能会无意中拦截这些关键流量。
|
||
|
||
<div id="header-forwarding-requirements">
|
||
#### 请求头转发要求
|
||
</div>
|
||
|
||
请确保你的 Worker 将 `Host` 头设置为你的 `<subdomain>.mintlify.site` 目标(如示例脚本所示),而不是直接透传原始请求的 `Host` 头。错误的 `Host` 头会导致验证请求失败。
|
||
|
||
<div id="configure-routing">
|
||
### 配置路由
|
||
</div>
|
||
|
||
在你的 Cloudflare 控制台中,选择 **Edit Code**,并添加 [Custom domain setup](https://app.mintlify.com/settings/deployment/custom-domain) 页面中已填入你自己值的脚本,或复制以下示例脚本。有关编辑 Worker 的更多信息,请参阅 [Cloudflare 文档](https://developers.cloudflare.com/workers-ai/get-started/dashboard/#development)。
|
||
|
||
<Tip>
|
||
如果使用示例脚本,请将 `[SUBDOMAIN]` 替换为你唯一的子域,将 `[YOUR_DOMAIN]` 替换为你网站的基础 URL;如果希望使用不同的子路径,则将 `/docs` 替换为你想要的子路径。
|
||
</Tip>
|
||
|
||
```javascript
|
||
addEventListener("fetch", (event) => {
|
||
event.respondWith(handleRequest(event.request));
|
||
});
|
||
|
||
async function handleRequest(request) {
|
||
try {
|
||
const urlObject = new URL(request.url);
|
||
|
||
// 如果请求是 Vercel 验证路径,允许其通过
|
||
if (urlObject.pathname.startsWith('/.well-known/')) {
|
||
return await fetch(request);
|
||
}
|
||
|
||
// 如果请求是 docs 子路径
|
||
if (/^\/docs/.test(urlObject.pathname)) {
|
||
// 然后代理到 Mintlify
|
||
const DOCS_URL = "[SUBDOMAIN].mintlify.site";
|
||
const CUSTOM_URL = "[YOUR_DOMAIN]";
|
||
|
||
let url = new URL(request.url);
|
||
url.hostname = DOCS_URL;
|
||
|
||
let proxyRequest = new Request(url, request);
|
||
|
||
proxyRequest.headers.set("Host", DOCS_URL);
|
||
proxyRequest.headers.set("X-Forwarded-Host", CUSTOM_URL);
|
||
proxyRequest.headers.set("X-Forwarded-Proto", "https");
|
||
// 如果部署到 Vercel,保留客户端 IP
|
||
proxyRequest.headers.set("CF-Connecting-IP", request.headers.get("CF-Connecting-IP"));
|
||
|
||
return await fetch(proxyRequest);
|
||
}
|
||
} catch (error) {
|
||
// 如果未找到操作,执行常规请求
|
||
return await fetch(request);
|
||
}
|
||
}
|
||
```
|
||
|
||
点击 **Deploy**,然后等待更改生效。
|
||
|
||
<Propagating />
|
||
|
||
|
||
<div id="test-your-worker">
|
||
### 测试你的 Worker
|
||
</div>
|
||
|
||
在部署代码后,测试你的 Worker,确保它正确路由到你的 Mintlify 文档。
|
||
|
||
1. 使用 Worker 的预览 URL 进行测试:`your-worker.your-subdomain.workers.dev/docs`
|
||
2. 确认该 Worker 能正确路由到你的 Mintlify 文档和你的网站。
|
||
|
||
<div id="add-custom-domain">
|
||
### 添加自定义 domain
|
||
</div>
|
||
|
||
1. 在你的 [Cloudflare 控制台](https://dash.cloudflare.com/)中,进入你的 Worker。
|
||
2. 前往 **Settings > Domains & Routes > Add > Custom Domain**。
|
||
3. 添加你的 domain。
|
||
|
||
<Tip>
|
||
我们建议同时添加带有 `www.` 和不带有 `www.` 的 domain。
|
||
</Tip>
|
||
|
||
有关更多信息,请参阅 Cloudflare 文档中的 [Add a custom domain](https://developers.cloudflare.com/workers/configuration/routing/custom-domains/#add-a-custom-domain)。
|
||
|
||
<div id="resolve-dns-conflicts">
|
||
### 解决 DNS 冲突
|
||
</div>
|
||
|
||
如果你的 domain 已经指向其他服务,你必须移除现有的 DNS 记录。你的 Cloudflare Worker 必须配置为接管该 domain 的全部流量。
|
||
|
||
1. 删除该 domain 的现有 DNS 记录。更多信息请参阅 Cloudflare 文档:[Delete DNS records](https://developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records/#delete-dns-records)。
|
||
2. 返回你的 Worker,添加你的自定义 domain。
|
||
|
||
<div id="webflow-custom-routing">
|
||
## Webflow 自定义路由
|
||
</div>
|
||
|
||
如果你使用 Webflow 托管主站点,并希望在同一 domain 的 `/docs` 路径下提供 Mintlify 文档,你需要通过 Cloudflare Workers 配置自定义路由,将所有非 docs 流量代理到你的主站点。
|
||
|
||
<Warning>
|
||
在部署此 Worker 之前,请确保你的主站点已配置为某个落地页,否则访问你主站点的访客可能会看到错误。
|
||
</Warning>
|
||
|
||
1. 在 Webflow 中,为你的主站点设置一个落地页,例如 `landing.yoursite.com`。这是访客访问你的网站时首先看到的页面。
|
||
2. 将你的主站点部署到该落地页。这样可以确保在你配置 Worker 的过程中,主站点依然可访问。
|
||
3. 为避免冲突,将主站点中的任何绝对 URL 更新为相对路径。
|
||
4. 在 Cloudflare 中选择 **Edit Code**,并将以下脚本添加到你的 Worker 代码中。
|
||
|
||
<Tip> 将 `[SUBDOMAIN]` 替换为你唯一的子域,将 `[YOUR_DOMAIN]` 替换为你网站的基础 URL,将 `[LANDING_DOMAIN]` 替换为你的落地页 URL,如有需要,将 `/docs` 替换为你想要的其他子路径。 </Tip>
|
||
|
||
```javascript
|
||
addEventListener("fetch", (event) => {
|
||
event.respondWith(handleRequest(event.request));
|
||
});
|
||
async function handleRequest(request) {
|
||
try {
|
||
const urlObject = new URL(request.url);
|
||
|
||
// 如果请求是 Vercel 验证路径,允许其通过
|
||
if (urlObject.pathname.startsWith('/.well-known/')) {
|
||
return await fetch(request);
|
||
}
|
||
|
||
// 如果请求是文档子路径
|
||
if (/^\/docs/.test(urlObject.pathname)) {
|
||
// 代理到 Mintlify
|
||
const DOCS_URL = "[SUBDOMAIN].mintlify.site";
|
||
const CUSTOM_URL = "[YOUR_DOMAIN]";
|
||
let url = new URL(request.url);
|
||
url.hostname = DOCS_URL;
|
||
let proxyRequest = new Request(url, request);
|
||
proxyRequest.headers.set("Host", DOCS_URL);
|
||
proxyRequest.headers.set("X-Forwarded-Host", CUSTOM_URL);
|
||
proxyRequest.headers.set("X-Forwarded-Proto", "https");
|
||
// 如果部署到 Vercel,保留客户端 IP
|
||
proxyRequest.headers.set("CF-Connecting-IP", request.headers.get("CF-Connecting-IP"));
|
||
return await fetch(proxyRequest);
|
||
}
|
||
// 将其他所有请求路由到主站点
|
||
const MAIN_SITE_URL = "[LANDING_DOMAIN]";
|
||
if (MAIN_SITE_URL && MAIN_SITE_URL !== "[LANDING_DOMAIN]") {
|
||
let mainSiteUrl = new URL(request.url);
|
||
mainSiteUrl.hostname = MAIN_SITE_URL;
|
||
return await fetch(mainSiteUrl, {
|
||
method: request.method,
|
||
headers: request.headers,
|
||
body: request.body
|
||
});
|
||
}
|
||
} catch (error) {
|
||
// 如果未找到匹配操作,处理常规请求
|
||
return await fetch(request);
|
||
}
|
||
}
|
||
```
|
||
|
||
5. 选择 **Deploy**,等待更改完成传播。
|
||
|
||
<Propagating />
|