首页 > 解决方案 > Apps 脚本中托管的书签在共享时无法运行

问题描述

在使用书签在 Apps Script 中部署我的网络应用程序后,它在我的端运行良好,但是当我尝试共享我的网络应用程序时,它会引发“不安全的 javascript”错误,例如从网络应用程序中单击它而不是作为书签。

Web 应用程序以用户访问权限运行,我们组织中的任何人都可以访问该应用程序。小书签的作用是提示输入并在当前页面上找到它。

代码如下:

<a id="bkmark">Link</a>

<script>
document.body.onload=()=>{
  google.script.run.withSuccessHandler(rep).getLink();
function rep(e){ 
document.querySelector('#bkmark').href = e; // return a javascript: IIFE wrapped in ``
}
}
</script>

我的 gs 从文件返回 Html 输出。任何帮助表示赞赏,谢谢!

标签: google-apps-scriptbookmarklet

解决方案


ContentService您可以使用模板直接导入,而不是将 JavaScript 添加为小册子:

Page.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script src="<?= ScriptApp.getService().getUrl() + '?getAction=true' ?>" type="text/javascript" defer async></script>
  </head>
  <body>
    <button id="trigger" onclick="doAction()" disabled>Click here to do something</button>
  </body>
</html>

Code.js

function doGet(e) {
  const { getAction } = e.parameter
  if (getAction !== undefined) {
    return genAction()
  }

  return HtmlService.createTemplateFromFile('Page').evaluate().setTitle("Booklet webapp")
}


function genAction() {
  return ContentService
    .createTextOutput(`
      function doAction() {
        alert("Hello world!")
      }

      (function loaded() {
        document.getElementById("trigger").disabled = false
      })();
    `)
    .setMimeType(ContentService.MimeType.JAVASCRIPT)
}

请注意,脚本标签有deferasync。这使得脚本在 DOM 完全加载后不会开始加载,并且它开始异步加载(不阻塞主线程)。

在 Apps 脚本方面,我们使用模板,因此我们可以动态获取脚本执行 URL (with ScriptApp.getService().getUrl()),我们添加一个查询参数 ( getAction),以便我们可以在doGet(e)函数上检测它。在那里我们检查那个参数,然后我们返回一个 JavaScript 内容。

还使按钮默认禁用,我添加了一个小代码,以便在脚本完成加载时启用按钮(它是异步的,因此可能需要一些时间才能完全加载)。

此技术还可用于通过获取结果、创建脚本元素和手动添加内容来动态添加脚本标签。

参考


推荐阅读