From b4cba469aae5230533850a73d663c7957f8e162b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=BB=E5=8B=87=E7=A5=A5?= <237899745@qq.com> Date: Mon, 24 Nov 2025 20:24:24 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8D=E9=82=AE?= =?UTF-8?q?=E4=BB=B6=E9=AA=8C=E8=AF=81=E9=93=BE=E6=8E=A5=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E6=80=A7=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 前端优化: - 新增 getTokenFromUrl() 方法,支持解析不规范的 URL 参数 - 新增 sanitizeUrlToken() 方法,统一清理 URL 中的 token - 兼容旧版邮件链接格式(缺少 ? 的情况) - 优化 URL 参数提取逻辑,使用正则表达式兼容多种格式 - 改进代码复用性,减少重复代码 问题修复: - 修复某些邮件客户端生成的链接无法正常解析 token 的问题 - 确保验证链接和重置链接在各种环境下都能正常工作 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- frontend/app.js | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/frontend/app.js b/frontend/app.js index 166d69e..ab377a9 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -246,6 +246,31 @@ createApp({ }, methods: { + // 提取URL中的token(兼容缺少 ? 的场景) + getTokenFromUrl(key) { + const currentHref = window.location.href; + const url = new URL(currentHref); + let token = url.searchParams.get(key); + + if (!token) { + const match = currentHref.match(new RegExp(`${key}=([\\w-]+)`)); + if (match && match[1]) { + token = match[1]; + } + } + return token; + }, + + // 清理URL中的token(同时处理路径和查询参数) + sanitizeUrlToken(key) { + const url = new URL(window.location.href); + url.searchParams.delete(key); + if (url.pathname.includes(`${key}=`)) { + url.pathname = url.pathname.split(`${key}=`)[0]; + } + window.history.replaceState({}, document.title, url.toString()); + }, + // 模态框点击外部关闭优化 - 防止拖动选择文本时误关闭 modalMouseDownTarget: null, handleModalMouseDown(e) { @@ -460,9 +485,7 @@ handleDragLeave(e) { this.verifyMessage = '邮箱验证成功,请登录'; this.isLogin = true; // 清理URL - const url = new URL(window.location.href); - url.searchParams.delete('verifyToken'); - window.history.replaceState({}, document.title, url.toString()); + this.sanitizeUrlToken('verifyToken'); } } catch (error) { console.error('邮箱验证失败:', error); @@ -1685,9 +1708,7 @@ handleDragLeave(e) { this.showResetPasswordModal = false; this.resetPasswordForm = { token: '', new_password: '' }; // 清理URL中的token - const url = new URL(window.location.href); - url.searchParams.delete('resetToken'); - window.history.replaceState({}, document.title, url.toString()); + this.sanitizeUrlToken('resetToken'); } } catch (error) { console.error('密码重置失败:', error); @@ -2240,16 +2261,17 @@ handleDragLeave(e) { // 初始化调试模式状态 this.debugMode = localStorage.getItem('debugMode') === 'true'; - // 处理URL中的验证/重置token - const url = new URL(window.location.href); - const verifyToken = url.searchParams.get('verifyToken'); - const resetToken = url.searchParams.get('resetToken'); + // 处理URL中的验证/重置token(兼容缺少?的旧链接) + const verifyToken = this.getTokenFromUrl('verifyToken'); + const resetToken = this.getTokenFromUrl('resetToken'); if (verifyToken) { this.handleVerifyToken(verifyToken); + this.sanitizeUrlToken('verifyToken'); } if (resetToken) { this.resetPasswordForm.token = resetToken; this.showResetPasswordModal = true; + this.sanitizeUrlToken('resetToken'); } // 阻止全局拖拽默认行为(防止拖到区域外打开新页面)