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

登录后无法跳转页面:Sandbox导航权限与用户激活问题

解决Google Apps Script中自动跳转的沙箱导航错误

登录后尝试自动导航到目标页面时触发以下错误:

错误信息:
来自URL为'https://n-x4qqieogl32dh7vitgxnysfogdq2h5ccinv5p6a-0lu-script.googleusercontent.com/userCodeAppPanel'的框架,尝试对源为'https://script.google.com'的框架发起导航,存在不安全操作。尝试导航顶级窗口的框架已被沙箱化,且带有'allow-top-navigation-by-user-activation'标记,但无用户激活(即手势)。

相关代码:

function ModelViewer(token) {
  if (!token) {
    console.log("No token found");
    return;
  }
   
      
    // Fetch the URL dynamically
  google.script.run.withSuccessHandler(function (appUrl) {
    console.log("Fetched URL:", appUrl);

  google.script.run.withSuccessHandler(function (isValid) {
    if (isValid) {
      console.log("isValid it is!")
      console.log("Token", token);
      const link = document.createElement('a');
      link.href = `${appUrl}?page=Models&token=${token}`;
      link.id = 'linkURL';
      document.body.appendChild(link);
      document.getElementById('linkURL').click();

    } else {
      console.log("isValid",isValid);
      console.log("Token", token);
      console.log("Invalid token. Redirecting to SignIn.");
      showNotification("Session expired. Please sign in again.", "error");
      }
    }).validateToken(token);
  }).getAppUrl(); // Call the server-side function to get the URL
}

问题原因

代码中通过link.click()自动触发跳转的操作,不符合Google Apps Script客户端沙箱的安全规则:顶级窗口导航必须由用户主动交互(如点击按钮、链接等手势操作)触发,异步回调中的自动点击不属于用户激活行为,因此被浏览器拦截。

修复方案

方案1:引导用户主动点击跳转

将自动跳转改为显示交互按钮,让用户手动完成导航:

function ModelViewer(token) {
  if (!token) {
    console.log("No token found");
    return;
  }
   
  google.script.run.withSuccessHandler(function (appUrl) {
    console.log("Fetched URL:", appUrl);

    google.script.run.withSuccessHandler(function (isValid) {
      if (isValid) {
        console.log("isValid it is!")
        console.log("Token", token);
        // 创建跳转按钮
        const jumpBtn = document.createElement('button');
        jumpBtn.textContent = '进入模型页面';
        jumpBtn.style.padding = '8px 16px';
        jumpBtn.addEventListener('click', () => {
          window.location.href = `${appUrl}?page=Models&token=${token}`;
        });
        document.body.appendChild(jumpBtn);

      } else {
        console.log("isValid",isValid);
        console.log("Token", token);
        console.log("Invalid token. Redirecting to SignIn.");
        showNotification("Session expired. Please sign in again.", "error");
      }
    }).validateToken(token);
  }).getAppUrl();
}

方案2:保留用户初始激活上下文

如果ModelViewer本身由用户点击操作触发(比如登录按钮),可以将异步操作封装为Promise,确保跳转在用户初始点击的事件链中完成:

// 假设登录按钮ID为loginBtn
document.getElementById('loginBtn').addEventListener('click', async function() {
  const token = await getLoginToken(); // 替换为实际获取token的逻辑
  if (!token) {
    console.log("No token found");
    return;
  }

  // 用Promise封装google.script.run的异步操作
  const getAppUrl = () => new Promise(resolve => google.script.run.withSuccessHandler(resolve).getAppUrl());
  const validateToken = (t) => new Promise(resolve => google.script.run.withSuccessHandler(resolve).validateToken(t));

  const appUrl = await getAppUrl();
  const isValid = await validateToken(token);

  if (isValid) {
    // 此时仍处于用户点击的激活状态,直接跳转不会被拦截
    window.location.href = `${appUrl}?page=Models&token=${token}`;
  } else {
    showNotification("Session expired. Please sign in again.", "error");
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 05:02:23