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

GAS单页应用使用google.script.history导航刷新后点击后退返回空白屏

问题描述

使用google.script.history.push和google.script.history.setChangeHandler开发Google Apps Script单页应用时,仅在页面刷新后点击浏览器前进/后退按钮会返回空白屏,未刷新时所有功能均正常。该问题可在谷歌Chrome(桌面端、移动端)、微软Edge浏览器复现,三星移动端浏览器运行正常。对桌面端用户影响较小,因为用户使用应用时很少主动刷新,但移动端用户上下滑动页面到顶/底部时容易误触刷新,会意外遇到空白屏问题。

复现步骤

  • 在浏览器中打开GAS应用,此时可见一个蓝色方块和2个按钮
  • 点击「Show Red ONLY」按钮,页面显示红色方块
  • 点击「Show Blue ONLY」按钮,页面显示蓝色方块
  • 点击浏览器「后退」按钮,页面正常显示红色方块,运行正常
  • 点击浏览器「前进」按钮,页面正常显示蓝色方块,无异常
  • 点击浏览器「刷新」按钮,页面依据URL的"Color"参数仍正常显示蓝色方块,无异常
  • 此时bug触发:点击浏览器「后退」按钮,预期显示红色方块,但实际返回空白屏

只要用户未刷新页面,使用浏览器前进/后退按钮在应用内导航均正常,问题是否复现取决于使用的浏览器类型。

原始代码

服务端脚本代码

function doGet(e){
    let htmltemplate = HtmlService.createTemplateFromFile("Home.html");
    let htmloutput = htmltemplate.evaluate();
    return htmloutput;
}

前端HTML代码(Home.html)

<!DOCTYPE html>
<html>
<head>
    <base target="_top">
</head>
<body>
    <button onclick="showRed();">Show Red ONLY</button>
    <button onclick="showBlue();">Show Blue ONLY</button>
    <div id="Red" style="width:200px; height: 200px; background-color:red;">Red Square</div>
    <div id="Blue" style="width:200px; height: 200px; background-color:blue;">Blue Square</div>

<script>
    function showRed(){
        let now = new Date();
        let state = {"timestamp": now.getTime()};
        let params = {"Color": "Red"};
        google.script.history.push(state, params);
        renderPage();
    }

    function showBlue(){
        let now = new Date();
        let state = {"timestamp": now.getTime()};
        let params = {"Color": "Blue"};
        google.script.history.push(state, params);
        renderPage();
    }

    function renderPage(){
        google.script.url.getLocation(function(location) {
            strColor = location.parameter.Color;
            
            if(strColor === "Red"){
                document.getElementById("Red").style.display = "block";
                document.getElementById("Blue").style.display = "none";
            }else{
                document.getElementById("Red").style.display = "none";
                document.getElementById("Blue").style.display = "block";
            }
        });
    }

    google.script.history.setChangeHandler(function (e) {
        renderPage()
    });

    document.addEventListener('DOMContentLoaded', renderPage());

</script>
</body>
</html>

问题根因

  1. DOMContentLoaded事件绑定错误:代码中写的是renderPage(),会在绑定事件时立即执行函数,而不是DOM加载完成后触发,导致初始状态渲染时序异常
  2. 异步API读取异常:google.script.url.getLocation是异步接口,页面刷新后调用历史栈导航时,该接口无法正确读取历史条目中的参数,导致strColor取值为undefined,两个方块都被设置为隐藏,出现空白屏
  3. 代码逻辑冗余:setChangeHandler的回调参数本身就包含了历史条目的参数和状态,不需要额外调用google.script.url.getLocation获取参数,增加了异步调用的时序风险

修复方案

修改Home.html中的script部分代码即可解决问题,核心改动为:修正DOM事件绑定逻辑、优先从历史事件对象取参数、增加默认显示逻辑避免空白。
修复后完整script代码如下:

function showRed(){
    let now = new Date();
    let state = {"timestamp": now.getTime()};
    let params = {"Color": "Red"};
    google.script.history.push(state, params);
    renderPage("Red");
}

function showBlue(){
    let now = new Date();
    let state = {"timestamp": now.getTime()};
    let params = {"Color": "Blue"};
    google.script.history.push(state, params);
    renderPage("Blue");
}

// 改造renderPage支持直接传入参数,避免异步读取异常
function renderPage(strColor = null){
    if(strColor){
        updateDisplay(strColor)
    }else{
        google.script.url.getLocation(function(location) {
            updateDisplay(location.parameter.Color);
        });
    }
}

// 抽离显示更新逻辑,增加默认值避免空白
function updateDisplay(strColor){
    if(strColor === "Red"){
        document.getElementById("Red").style.display = "block";
        document.getElementById("Blue").style.display = "none";
    }else{
        document.getElementById("Red").style.display = "none";
        document.getElementById("Blue").style.display = "block";
    }
}

// 从历史事件对象直接取参数,不需要再异步读url
google.script.history.setChangeHandler(function (e) {
    renderPage(e.parameter.Color)
});

// 修正事件绑定,传函数引用而不是执行结果
document.addEventListener('DOMContentLoaded', renderPage);

内容的提问来源于stack exchange,提问作者Gaston Doiron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:24:03