fix(web): SSE 活动流默认同源,修复反代部署连不上 :8787
sseUrl() 原先无条件把 SSE 地址拼成 ${hostname}:8787,连生产静态导出
也带这个硬编码。反代到 443 的部署里页面从 https://域名/ 加载,SSE 却被
指向 https://域名:8787/...,而 8787 未对公网开放,导致活动流连不上、反复重连。
改为用 NODE_ENV 区分:生产默认同源(相对路径),仅 next dev 保留 :8787
以绕过 Next.js /api 反代对 SSE 的缓冲。NEXT_PUBLIC_SSE_BASE 覆盖口保留。
验证:NEXT_EXPORT=1 next build 后生产包里 :8787 分支已被 tree-shake。
补充 README 反向代理部署文档(同源说明 + nginx 关缓冲配置)。
Closes #169
This commit is contained in:
1 parent
160fe13c24
commit
e2c8a23a98
2 files changed
+48
-9
No files matched your search
+19
-9
@@ -146,14 +146,22 @@ export async function http<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
return r.json();
|
||||
}
|
||||
|
||||
// sseUrl builds a URL for Server-Sent Events streams. SSE must NOT go through the
|
||||
// Next.js dev `/api` rewrite: that proxy buffers the streamed response, so event
|
||||
// frames never reach the browser (the EventSource opens but receives 0 messages).
|
||||
// We therefore connect straight to the Go backend, whose CORS is open. Override
|
||||
// with NEXT_PUBLIC_SSE_BASE; set it to "" to force same-origin (e.g. behind a
|
||||
// production reverse proxy that flushes SSE correctly).
|
||||
// Token is appended as ?token= because SSE bypasses the Next.js proxy and the
|
||||
// browser does not send cookies cross-port.
|
||||
// sseUrl builds a URL for Server-Sent Events streams.
|
||||
//
|
||||
// Production (static export / Docker): the Go backend serves the web UI *and* the
|
||||
// SSE streams on the same port, so we default to a same-origin (relative) URL.
|
||||
// This is what makes reverse-proxy deploys work: a page loaded from
|
||||
// https://<domain>/ connects to https://<domain>/api/..., which the proxy forwards
|
||||
// to the backend — no need to expose :8787 publicly. Hardcoding :8787 here used to
|
||||
// break exactly that (https://<domain>:8787/... is unreachable when only 443 is open).
|
||||
//
|
||||
// Dev (next dev): SSE must NOT go through the Next.js `/api` rewrite — that proxy
|
||||
// buffers the streamed response, so event frames never reach the browser (the
|
||||
// EventSource opens but receives 0 messages). So in dev only we connect straight
|
||||
// to the Go backend on :8787, whose CORS is open.
|
||||
//
|
||||
// Override either default with NEXT_PUBLIC_SSE_BASE (set it to "" to force same-origin).
|
||||
// Token is appended as ?token= because SSE can't carry cookies cross-origin.
|
||||
// mockReport returns a canned Markdown report for the demo.
|
||||
function mockReport(_task?: string): string {
|
||||
return `# ARTEX 渗透测试报告 — Acme Corp
|
||||
@@ -180,7 +188,9 @@ function mockReport(_task?: string): string {
|
||||
export function sseUrl(path: string): string {
|
||||
const base =
|
||||
process.env.NEXT_PUBLIC_SSE_BASE ??
|
||||
(typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8787` : "");
|
||||
(process.env.NODE_ENV !== "production" && typeof window !== "undefined"
|
||||
? `${window.location.protocol}//${window.location.hostname}:8787`
|
||||
: "");
|
||||
const token = getToken();
|
||||
const sep = path.includes("?") ? "&" : "?";
|
||||
return token ? `${base}${path}${sep}token=${encodeURIComponent(token)}` : `${base}${path}`;
|
||||
|
||||
Reference in new issue
Block a user