From e7a49340686d63495f752beeba4b4b5b400a915a Mon Sep 17 00:00:00 2001 From: dekun Date: Thu, 1 Oct 2026 11:51:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9C=AA=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=97=B6=20API=20=E8=BF=94=E5=9B=9E=20HTML=20=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E6=9C=9F=E6=9D=83=E9=93=BE=20JSON=20=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=A4=B1=E8=B4=A5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit API 统一返回 401 JSON,并改进前端非 JSON 错误提示。 Co-authored-by: Cursor --- app.py | 9 +++++++++ lib/common/static/options_panel.js | 16 +++++++++++++++- lib/options/templates/options_panel.html | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app.py b/app.py index eeebf14..8138ca0 100644 --- a/app.py +++ b/app.py @@ -5157,6 +5157,15 @@ def login_required(f): def decorated(*args, **kwargs): if AUTH_DISABLED or bool(session.get("logged_in")): return f(*args, **kwargs) + # API 必须返回 JSON,否则前端 r.json() 会报 Unexpected token... + path = request.path or "" + wants_json = ( + path.startswith("/api/") + or (request.headers.get("X-Requested-With") or "").lower() == "xmlhttprequest" + or "application/json" in (request.headers.get("Accept") or "") + ) + if wants_json: + return jsonify({"ok": False, "msg": "未登录或会话过期,请重新登录"}), 401 return redirect("/login") return decorated diff --git a/lib/common/static/options_panel.js b/lib/common/static/options_panel.js index c8677d5..6c75021 100644 --- a/lib/common/static/options_panel.js +++ b/lib/common/static/options_panel.js @@ -78,7 +78,21 @@ async function apiJson(url, opts) { const r = await fetch(url, Object.assign({ credentials: "same-origin" }, opts || {})); - return r.json(); + const text = await r.text(); + let data = null; + try { + data = text ? JSON.parse(text) : null; + } catch (e) { + if (/\/login/i.test(r.url || "") || /^\s* - +