From d3c5b4c27ad1268b13f57bd2e21963f2b066ccd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=B9=E5=B0=BC=E5=B0=94?= Date: Wed, 11 Mar 2026 11:27:57 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/main.py | 25 ++++++++++++++++++++++--- run-docker.sh | 13 ++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/backend/main.py b/backend/main.py index 318eaa9..91a3214 100644 --- a/backend/main.py +++ b/backend/main.py @@ -10,7 +10,7 @@ from urllib.parse import urlencode import httpx from fastapi import FastAPI, HTTPException, Query, Request from fastapi.middleware.cors import CORSMiddleware -from fastapi.responses import HTMLResponse +from fastapi.responses import HTMLResponse, Response from pydantic import BaseModel try: @@ -431,7 +431,8 @@ def _slider_form_html(key_val: str, data62_val: str, ticket_val: str) -> str: k = html.escape(key_val, quote=True) d = html.escape(data62_val, quote=True) t = html.escape(ticket_val, quote=True) - script_src = html.escape(f"{SLIDER_VERIFY_BASE_URL.rstrip('/')}/assets/N_jYM_2V.js", quote=True) + # 脚本走本机代理 /auth/slider-assets/...,避免跨域加载 7765 被 CORS 拦截 + script_src = "/auth/slider-assets/N_jYM_2V.js" return f""" @@ -477,13 +478,31 @@ def _slider_form_html(key_val: str, data62_val: str, ticket_val: str) -> str: """ +@app.get("/auth/slider-assets/{path:path}") +async def slider_asset_proxy(path: str): + """代理 7765 的 assets(如 N_jYM_2V.js),避免跨域加载被 CORS 拦截。""" + url = f"{SLIDER_VERIFY_BASE_URL.rstrip('/')}/assets/{path}" + try: + async with httpx.AsyncClient(timeout=15.0) as client: + resp = await client.get(url) + if resp.status_code >= 400: + raise HTTPException(status_code=resp.status_code, detail=resp.text[:200]) + media_type = "application/javascript" if path.endswith(".js") else "application/octet-stream" + return Response(content=resp.content, media_type=media_type) + except HTTPException: + raise + except Exception as e: + logger.warning("Slider asset proxy error: %s", e) + raise HTTPException(status_code=502, detail=str(e)) from e + + @app.get("/auth/slider-form", response_class=HTMLResponse) async def slider_form( key: str = Query(..., description="Key(提交到第三方滑块)"), data62: str = Query("", description="Data62"), ticket: str = Query(..., description="Original Ticket"), ): - """本地滑块验证页:与 7765 同 DOM(#app、keyInput、data62Input、originalTicketInput),加载 7765 的 module 脚本,不用 iframe。""" + """本地滑块验证页:与 7765 同 DOM,脚本经本机代理加载,避免 CORS。""" data62 = _clean_data62(data62) return HTMLResponse(content=_slider_form_html(key, data62, ticket)) diff --git a/run-docker.sh b/run-docker.sh index 78ab977..ac5fb66 100755 --- a/run-docker.sh +++ b/run-docker.sh @@ -1,14 +1,25 @@ #!/usr/bin/env bash # 生产部署脚本:启动前拉取最新代码 → 构建镜像 → 停止旧容器 → 启动新容器 +# 用法: ./run-docker.sh [-p PORT] [-d HOST_DATA_DIR] +# -p, --port PORT 宿主机端口,默认 3000 +# -d, --data-dir DIR 数据目录挂载,默认 ./data set -e IMAGE_NAME="wechat-admin-backend" CONTAINER_NAME="wechat-admin-backend" PORT="${PORT:-3000}" -# 数据目录挂载到宿主机,防止容器删除后丢失(SQLite 库 wechat.db 及表数据) HOST_DATA_DIR="${HOST_DATA_DIR:-$(pwd)/data}" +while [[ $# -gt 0 ]]; do + case $1 in + -p|--port) PORT="$2"; shift 2 ;; + -d|--data-dir) HOST_DATA_DIR="$2"; shift 2 ;; + -h|--help) echo "Usage: $0 [-p PORT] [-d HOST_DATA_DIR]"; echo " -p, --port PORT default 3000"; echo " -d, --data-dir DIR default \$(pwd)/data"; exit 0 ;; + *) echo "Unknown option: $1 (use -h for help)"; exit 1 ;; + esac +done + # 启动前自动获取最新代码(与远端 master 一致,丢弃本地修改) if git rev-parse --git-dir >/dev/null 2>&1; then echo "Fetching and reset to origin/master..."