Skip to content
Cloudflare Docs
非官方翻译 - 此文档为非官方中文翻译版本,仅供参考。如有疑问请以 英文官方文档 为准。

静态前端,容器后端

一个带有容器化后端的简单前端应用

一个常见的模式是使用静态资产提供静态前端应用程序(例如 React、Vue、Svelte), 然后将后端请求传递给容器化的后端应用程序。

在此示例中,我们将展示一个使用作为静态资产提供的简单 index.html 文件的示例, 但您可以从许多前端框架中选择一个。有关更多信息,请参阅我们的 Workers 框架示例

有关完整示例,请参阅 静态前端 + 容器后端模板

配置静态资产和容器

{
"name": "cron-container",
"main": "src/index.ts",
"assets": {
"directory": "./dist",
"binding": "ASSETS"
},
"containers": [
{
"class_name": "Backend",
"image": "./Dockerfile",
}
],
"durable_objects": {
"bindings": [
{
"class_name": "Backend",
"name": "BACKEND"
}
]
},
"migrations": [
{
"new_sqlite_classes": [
"Backend"
],
"tag": "v1"
}
]
}

添加一个简单的 index.html 文件来提供服务

./dist 目录中创建一个简单的 index.html 文件。

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小部件</title>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/3.13.3/cdn.min.js"></script>
</head>
<body>
<div x-data="widgets()" x-init="fetchWidgets()">
<h1>小部件</h1>
<div x-show="loading">加载中...</div>
<div x-show="error" x-text="error" style="color: red;"></div>
<ul x-show="!loading && !error">
<template x-for="widget in widgets" :key="widget.id">
<li>
<span x-text="widget.name"></span> - (ID: <span x-text="widget.id"></span>)
</li>
</template>
</ul>
<div x-show="!loading && !error && widgets.length === 0">
未找到小部件。
</div>
</div>
<script>
function widgets() {
return {
widgets: [],
loading: false,
error: null,
async fetchWidgets() {
this.loading = true;
this.error = null;
try {
const response = await fetch('/api/widgets');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
this.widgets = await response.json();
} catch (err) {
this.error = err.message;
} finally {
this.loading = false;
}
}
}
}
</script>
</body>
</html>

在此示例中,我们使用 Alpine.js/api/widgets 获取小部件列表。

这是一个非常简单的示例,但您可以变得非常复杂。 有关更多信息,请参阅 Workers 与前端框架集成的示例

定义 Worker

您的 Worker 需要能够提供静态资产并将请求路由到容器化后端。

在这种情况下,如果路由以 /api 开头,我们将请求传递给三个容器实例之一, 所有其他请求将作为静态资产提供。

import { Container, getRandom } from "@cloudflare/containers";
const INSTANCE_COUNT = 3;
class Backend extends Container {
defaultPort = 8080; // 将请求传递到容器中的端口 8080
sleepAfter = "2h"; // 只有在 2 小时内没有收到请求时才让容器进入睡眠状态
}
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname.startsWith("/api")) {
// 注意:"getRandom" 将在不久的将来被延迟感知路由替换
const containerInstance = getRandom(env.BACKEND, INSTANCE_COUNT);
return containerInstance.fetch(request);
}
return env.ASSETS.fetch(request);
},
};

定义后端容器

您的容器应该能够处理对 /api/widgets 的请求。

在这种情况下,我们将使用一个简单的 Golang 后端,该后端返回一个硬编码的小部件列表。

server.go

package main
import (
"encoding/json"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r \*http.Request) {
widgets := []map[string]interface{}{
{"id": 1, "name": "小部件 A"},
{"id": 2, "name": "链轮 B"},
{"id": 3, "name": "齿轮 C"},
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
json.NewEncoder(w).Encode(widgets)
}
func main() {
http.HandleFunc("/api/widgets", handler)
log.Println("在端口 8080 上启动服务器")
log.Fatal(http.ListenAndServe(":8080", nil))
}

通过此设置,您现在有一个静态前端应用程序,它使用容器化后端从 /api/widgets 获取数据。

前端将在 HTML 页面中显示小部件列表,而后端在容器中运行并响应 API 请求。