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*
-
+