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

如何在Google Apps Script中传递对象变量并加载含外部JS的HTML页面

问题分析与修复方案

你的页面空白且无报错(实际是语法错误被静默处理),核心问题集中在模板变量赋值错误、JS语法错误、DOM元素缺失这几个方面,以下是具体问题和修复代码:

1. 服务器端模板变量赋值错误

在getNewPageContent函数中,错误使用链式赋值apDahboardHtml.obj = obj = {...},未定义的obj会导致模板变量赋值失败,同时还漏传了userId到模板对象中。

修复后的代码:

const getNewPageContent = (clientType, clientName, clientId, userId, userFirstName, userLastName) => {
  if (clientType === "AP") {
    const apDashboardJs = "ap_dashboard_js";
    let apDahboardHtml = HtmlService.createTemplateFromFile("ap_dashboard_js");
    // 直接赋值模板变量,补上缺失的userId
    apDahboardHtml.obj = {
      typeOfClient: clientType,
      nameOfClient: clientName,
      idOfClient: clientId,
      userId: userId,
      userFirstName: userFirstName,
      userLastName: userLastName
    };
    const apDashboardHtml2Content = apDahboardHtml.evaluate().getContent();
    const apDashboardHtmlWindow = HtmlService.createTemplateFromFile("ap_dashboard");
    apDashboardHtmlWindow[apDashboardJs] = apDashboardHtml2Content;
    // 返回HTML字符串而非HtmlOutput对象,避免客户端解析问题
    return apDashboardHtmlWindow.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL).getContent();
  }
  return ContentService.createTextOutput('ok');
};

2. JS模板中字符串变量未加引号导致语法错误

直接输出字符串变量会产生无效JS代码(比如let clientName = 张三;),必须用JSON.stringify包裹,确保特殊字符被正确转义。同时要先判断DOM元素是否存在再绑定事件,避免执行中断。

修复后的JS代码:

<script>
function addEventListenerToDashBtn() {
  const dashboardContainer = document.getElementById('dashboard-container');
  if (dashboardContainer) {
    dashboardContainer.addEventListener('click', function() {
      dashboardContainer.classList.toggle("activeBtn");
    });
  }
}
addEventListenerToDashBtn();

// 先判断元素存在性再操作
let cardsContainer = document.querySelector('.cards-container');
let navbarTitle = document.querySelector('#navbar-title');
let sideBar = document.querySelector('.side-bar');
let arrowCollapse = document.querySelector('#logo-name__icon');
let topLevelList = document.getElementById('top-level-list');

if (arrowCollapse) {
  arrowCollapse.addEventListener('click', (event) => {
    event.stopPropagation();
    if (sideBar) sideBar.classList.toggle('collapse');
    arrowCollapse.classList.toggle('collapse');
    if (cardsContainer) cardsContainer.classList.toggle('stretch');
    if (navbarTitle) navbarTitle.classList.toggle('stretch');

    if (arrowCollapse.classList.contains('collapse')) {
      arrowCollapse.className = 'bx bx-arrow-from-left logo-name__icon collapse';
      if (topLevelList) topLevelList.style.display = 'none';
    } else {
      arrowCollapse.className = 'bx bx-arrow-from-right logo-name__icon';
      if (topLevelList) topLevelList.style.display = 'block';
    }
  });
}

if (sideBar && arrowCollapse) {
  sideBar.addEventListener('click', (event) => {
    if (event.target === arrowCollapse) {
      event.stopPropagation();
    }
  });
}

// 用JSON.stringify确保字符串变量语法正确
let clientName = <?!= JSON.stringify(obj.nameOfClient) ?>;
let clientType = <?!= JSON.stringify(obj.typeOfClient) ?>;
let clientId = <?!= JSON.stringify(obj.idOfClient) ?>;
let userId = <?!= JSON.stringify(obj.userId) ?>;
let userFirstName = <?!= JSON.stringify(obj.userFirstName) ?>;
let userLastName = <?!= JSON.stringify(obj.userLastName) ?>;
let fullName = userFirstName + " " + userLastName;

// 先判断元素存在性再修改内容
const clientNameHeader = document.getElementById('clientNameHeader');
if (clientNameHeader) {
  clientNameHeader.textContent = clientName;
}

const fullNameOption = document.getElementById('full-name-option');
if (fullNameOption) {
  fullNameOption.value = fullName;
  fullNameOption.text = fullName;
}
</script>

3. HTML页面缺失必要DOM元素

JS代码中引用的clientNameHeader、dashboard-container等元素在HTML中不存在,导致JS执行中断。需要补充这些元素,并将CSS移到<head>避免渲染阻塞。

修复后的HTML代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <base target="_top">
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <!-- 把CSS移到head中 -->
  <?!= HtmlService.createHtmlOutputFromFile('ap_dashboard_css').getContent() ?>
</head>
<body>
  <nav class="navbar">
    <h3 id="navbar-title">Dashboard</h3>
    <!-- 补充缺失的clientNameHeader元素 -->
    <h4 id="clientNameHeader"></h4>
    <div class="user-info">
      <div class="user-avatar">
        <a href="#"><i class="bx bx-user avatar avatar-sm"></i></a>
      </div>
      <div class="user-details">
        <div class="user-dropdown">
          <select id="user-dropdown" class="styled-select">
              <option value="" id="full-name-option" selected></option>
              <option value="Logout">Logout</option>
            </select>
        </div>
      </div>
    </div>
  </nav>
  <!-- 补充JS依赖的DOM元素 -->
  <div id="dashboard-container" class="dashboard-container">Dashboard Button</div>
  <div class="side-bar">
    <div id="logo-name__icon" class="bx bx-arrow-from-right logo-name__icon"></div>
    <ul id="top-level-list">
      <li>Menu Item</li>
    </ul>
  </div>
  <div class="container">
    <div class="cards-container">Cards Area</div>
  </div>
  
  <?!= ap_dashboard_js ?>
</body>
</html>

4. 客户端页面替换逻辑优化

在signIn函数中,添加错误捕获逻辑,同时优化脚本重新执行的方式,确保页面能正常渲染。

修复后的signIn代码:

const signIn = (event) => {
  event.preventDefault();
  const userId = document.getElementById("email-input").value;
  const pwd = document.getElementById("pwd-input").value;
  
  google.script.run
    .withSuccessHandler(function(validSession) {
      if (validSession === "wrong password") {
        document.body.innerHTML = validSession;
        return;
      }
      
      const { clientType, clientName, id: clientId, userId, userFirstName, userLastName } = validSession;
      if (clientType === "AP") {
        console.log("AP Page called successfully.");
        google.script.run
          .withSuccessHandler(function(newPageContent) {
            document.body.innerHTML = newPageContent;
            // 重新执行页面脚本的可靠方式
            document.querySelectorAll('script').forEach(script => {
              const newScript = document.createElement('script');
              newScript.text = script.text;
              document.head.appendChild(newScript).remove();
            });
          })
          .withFailureHandler(error => {
            console.error('加载页面失败:', error);
            document.body.innerHTML = '加载页面失败,请刷新重试';
          })
          .getNewPageContent(clientType, clientName, clientId, userId, userFirstName, userLastName);
      }
    })
    .withFailureHandler(error => {
      console.error('登录验证失败:', error);
      document.body.innerHTML = '登录验证失败,请刷新重试';
    })
    .checkLogin("log-in credentials", "", userId, pwd);
};

调试技巧

  1. 按F12打开浏览器开发者工具,查看Console标签页,能看到之前被忽略的JS语法错误;
  2. 查看Network标签页,检查google.script.run的请求响应,确认服务器端是否正确返回HTML;
  3. 在服务器端函数中添加console.log,验证变量传递是否正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:59:56