google-apps-script - 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 输出。任何帮助表示赞赏,谢谢!
解决方案
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)
}
请注意,脚本标签有defer
和async
。这使得脚本在 DOM 完全加载后不会开始加载,并且它开始异步加载(不阻塞主线程)。
在 Apps 脚本方面,我们使用模板,因此我们可以动态获取脚本执行 URL (with ScriptApp.getService().getUrl()
),我们添加一个查询参数 ( getAction
),以便我们可以在doGet(e)
函数上检测它。在那里我们检查那个参数,然后我们返回一个 JavaScript 内容。
还使按钮默认禁用,我添加了一个小代码,以便在脚本完成加载时启用按钮(它是异步的,因此可能需要一些时间才能完全加载)。
此技术还可用于通过获取结果、创建脚本元素和手动添加内容来动态添加脚本标签。
参考
推荐阅读
- angular - 将数据加载到网格后不显示滚动条
- ios - 单元格更新数据库后,UI 阻塞;我该如何解决?
- java - LSP(里氏替换原则)如何工作
- r - 在 R 中使用 formattable 组合列
- php - PHP/Laravel:只要有事情发生就运行函数
- java - 如何使用 context.xml 正确连接到 XAMPP mySQL DB
- python - 预计会看到 1 个数组,但得到了以下 4 个数组的列表
- java - 如何从 Java 中的 RESTFul 服务向 Ipstack API 请求 GET
- javascript - 单击时显示/隐藏 div,并在当前项目上单击更改类
- javascript - 仅针对 CSS 中父子对象中相同类的第一个直接匹配