You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Apps Script因sandboxFrame无法页面重定向的解决方法

解决Google Apps Script WebApp因sandboxFrame导致的页面重定向问题

问题根源

WebApp的HTML页面运行在Google的sandboxFrame中,直接使用window.location.href = 'login.html'无法正确跳转——因为login.html不是独立可访问的资源,而是通过doGet()动态返回的;另外google.script.host.close()仅适用于对话框/侧边栏场景,直接访问WebApp时调用该方法会干扰重定向逻辑。


具体修改方案

1. 调整登录成功后的逻辑

登录验证通过后,直接刷新页面让doGet()重新判断用户状态并返回主页,无需调用google.script.host.close()和多余的setUserLoggedIn()方法。

修改login.html中的loginSuccess函数:

function loginSuccess(isAuthenticated) {
    if (isAuthenticated) {
        // 刷新顶层窗口,触发doGet重新加载对应页面
        window.top.location.reload();
    } else {
        alert("用户名或密码错误,请重试。");
    }
}

2. 调整登出逻辑

登出完成后,直接重定向到WebApp根地址,让doGet()返回登录页面,移除无效的google.script.host.close()调用。

修改main.html中的logout函数:

function logout() {
    google.script.run.withSuccessHandler(function() {
        // 重定向到WebApp根地址,触发登录页加载
        window.top.location.href = '/';
    }).logoutUser();
}

3. 简化服务器端登出函数

移除logoutUser()中多余的HTML输出返回,仅保留会话清理逻辑:

function logoutUser() {
    var userProperties = PropertiesService.getUserProperties();
    userProperties.deleteProperty('loggedIn'); // 结束会话
}

修改后的完整代码

login.html

<!DOCTYPE html>
<html>
<head>
    <base target="_top">
    <style>
        body { font-family: Arial, sans-serif; }
        .form-container { margin: 20px; }
        .form-input { padding: 10px; margin-bottom: 10px; width: 100%; }
        .form-submit { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; cursor: pointer; width: 100%; }
        .form-submit:hover { background-color: #45a049; }
    </style>
</head>
<body>
    <div class="form-container">
        <h2>登录</h2>
        <form>
            <input class="form-input" type="text" id="username" name="username" placeholder="用户名" required><br>
            <input class="form-input" type="password" id="password" name="password" placeholder="密码" required><br>
            <input class="form-submit" type="button" value="登录" onclick="submitForm()">
        </form>
    </div>
    
    <script>
        function submitForm() {
            var username = document.getElementById("username").value;
            var password = document.getElementById("password").value;
            
            google.script.run.withSuccessHandler(loginSuccess).authenticateUser(username, password);
        }
        
        function loginSuccess(isAuthenticated) {
            if (isAuthenticated) {
                window.top.location.reload();
            } else {
                alert("用户名或密码错误,请重试。");
            }
        }
    </script>
</body>
</html>

main.html

<!DOCTYPE html>
<html>
<head>
    <base target="_top">
    <style>
        body { font-family: Arial, sans-serif; }
        .logout-button { padding: 10px 20px; background-color: #f44336; color: white; border: none; cursor: pointer; }
        .logout-button:hover { background-color: #da190b; }
    </style>
</head>
<body>
    <h2>欢迎!</h2>
    <button class="logout-button" onclick="logout()">退出登录</button>
    
    <script>
        function logout() {
            google.script.run.withSuccessHandler(function() {
                window.top.location.href = '/';
            }).logoutUser();
        }
    </script>
</body>
</html>

code.gs

function doGet() {
    var userProperties = PropertiesService.getUserProperties();
    var loggedIn = userProperties.getProperty('loggedIn');
    
    if (loggedIn === 'true') {
        return HtmlService.createHtmlOutputFromFile('main').setTitle('主页');
    } else {
        return HtmlService.createHtmlOutputFromFile('login').setTitle('登录');
    }
}

function authenticateUser(username, password) {
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('user');
    var dataRange = sheet.getDataRange();
    var values = dataRange.getValues();
    
    for (var i = 0; i < values.length; i++) {
        var savedUsername = values[i][0]; // 假设用户名列在A列
        var savedPassword = values[i][1]; // 假设密码列在B列
        
        if (savedUsername === username && savedPassword === password) {
            var userProperties = PropertiesService.getUserProperties();
            userProperties.setProperty('loggedIn', 'true');
            return true; // 用户验证通过
        }
    }
    
    return false; // 用户验证失败
}

function logoutUser() {
    var userProperties = PropertiesService.getUserProperties();
    userProperties.deleteProperty('loggedIn'); // 结束会话
}

内容的提问来源于stack exchange,提问作者First Point

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:34:51