Skip to content

Commit 5af1cc0

Browse files
committed
修复前端远程访问 API 失败
- 前端默认使用同源 /api 请求,由 Next.js 代理到后端 - 支持通过 NEXT_SERVER_API_BASE_URL 配置后端代理地址 - 避免浏览器直连后端端口导致 Failed to fetch - 背景:GitHub issue #65 反馈粘贴视频链接后创建任务无反应 - 影响:提升局域网、远程主机和 Tailscale 访问 WebUI 时的可用性
1 parent 6ca731f commit 5af1cc0

5 files changed

Lines changed: 44 additions & 13 deletions

File tree

README.en.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,12 @@ Frontend:
224224
npm --prefix apps/web run dev -- --hostname 0.0.0.0 --port 3000
225225
```
226226

227+
By default, the frontend calls same-origin `/api/...` URLs and Next.js proxies them to `http://127.0.0.1:8000`. If the backend is not on local port `8000`, set `NEXT_SERVER_API_BASE_URL` when starting the frontend, for example:
228+
229+
```bash
230+
NEXT_SERVER_API_BASE_URL=http://192.168.1.10:8000 npm --prefix apps/web run dev -- --hostname 0.0.0.0 --port 3000
231+
```
232+
227233
Open:
228234

229235
```text

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,12 @@ npm --prefix apps/web run dev -- --hostname 0.0.0.0 --port 3000
224224
npm --prefix apps/web run dev -- --hostname 0.0.0.0 --port 3000
225225
```
226226

227+
前端默认通过同源 `/api/...` 请求访问后端,并由 Next.js 代理到 `http://127.0.0.1:8000`。如果后端不在本机 `8000` 端口,启动前端时设置 `NEXT_SERVER_API_BASE_URL`,例如:
228+
229+
```bash
230+
NEXT_SERVER_API_BASE_URL=http://192.168.1.10:8000 npm --prefix apps/web run dev -- --hostname 0.0.0.0 --port 3000
231+
```
232+
227233
打开:
228234

229235
```text

apps/web/next.config.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
11
import type { NextConfig } from "next";
22

3+
function apiProxyTarget() {
4+
const configured =
5+
process.env.NEXT_SERVER_API_BASE_URL ||
6+
process.env.NEXT_PUBLIC_API_BASE_URL ||
7+
"http://127.0.0.1:8000";
8+
return configured.replace(/\/$/, "");
9+
}
10+
311
const nextConfig: NextConfig = {
412
allowedDevOrigins: ["172.27.2.90", "100.94.222.54"],
13+
async rewrites() {
14+
return [
15+
{
16+
source: "/api/:path*",
17+
destination: `${apiProxyTarget()}/api/:path*`,
18+
},
19+
];
20+
},
521
};
622

723
export default nextConfig;

apps/web/src/app/page.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import Link from "next/link"
44
import { useRouter } from "next/navigation"
5-
import { FormEvent, useCallback, useEffect, useState } from "react"
5+
import { FormEvent, useEffect, useState } from "react"
66
import { ChevronRight, Play } from "lucide-react"
77

88
import {
@@ -53,24 +53,25 @@ export default function Home() {
5353
const [error, setError] = useState("")
5454
const [submitting, setSubmitting] = useState(false)
5555

56-
const refreshTasks = useCallback(async () => {
56+
async function refreshTasks() {
5757
const { tasks: list } = await listTasks()
5858
setTasks(list)
59-
}, [])
59+
}
6060

6161
useEffect(() => {
6262
let cancelled = false
63-
const load = async () => {
63+
64+
const loadTasks = async () => {
6465
try {
6566
const { tasks: list } = await listTasks()
66-
if (cancelled) return
67-
setTasks(list)
67+
if (!cancelled) setTasks(list)
6868
} catch (err) {
6969
if (!cancelled) setError(err instanceof Error ? err.message : t.home.loadError)
7070
}
7171
}
72-
load()
73-
const interval = window.setInterval(load, 2000)
72+
73+
loadTasks()
74+
const interval = window.setInterval(loadTasks, 2000)
7475
return () => {
7576
cancelled = true
7677
window.clearInterval(interval)

apps/web/src/lib/api.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
function defaultApiBase(): string {
2-
if (typeof window === "undefined") return "http://localhost:8000"
3-
return `${window.location.protocol}//${window.location.hostname}:8000`
1+
function configuredApiBase(): string {
2+
const configured = process.env.NEXT_PUBLIC_API_BASE_URL?.trim()
3+
if (configured) return configured.replace(/\/$/, "")
4+
5+
if (typeof window === "undefined") return "http://127.0.0.1:8000"
6+
return ""
47
}
58

6-
export const API_BASE =
7-
process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/$/, "") || defaultApiBase()
9+
export const API_BASE = configuredApiBase()
810

911
export type StageStatus = "pending" | "running" | "succeeded" | "failed"
1012
export type TaskStatus = "queued" | "running" | "succeeded" | "failed"

0 commit comments

Comments
 (0)