托管在 Apps 脚本中的小书签在共享时无法 运行
Bookmarklet hosted in Apps Script unable to run when shared
在带有书签的 Apps 脚本中部署我的 Web 应用程序后,它在我这边运行良好,但是当我尝试共享我的 Web 应用程序时,它抛出一个 'unsafe javascript' 错误,就像从 Web 应用程序中单击它一样而不是作为书签。
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 returns 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(使用 ScriptApp.getService().getUrl()
),并且我们添加了一个查询参数(getAction
),所以我们可以在 doGet(e)
函数上检测到它。在那里我们检查该参数,我们得到了 return 一个 JavaScript 内容。
默认情况下禁用按钮,我添加了一个小代码,以便在脚本完成加载时启用按钮(它是异步的,因此可能需要一些时间才能完全加载)。
此技术还可用于通过获取结果、创建脚本元素并手动添加内容来动态添加脚本标签。
参考资料
在带有书签的 Apps 脚本中部署我的 Web 应用程序后,它在我这边运行良好,但是当我尝试共享我的 Web 应用程序时,它抛出一个 'unsafe javascript' 错误,就像从 Web 应用程序中单击它一样而不是作为书签。
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 returns 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(使用 ScriptApp.getService().getUrl()
),并且我们添加了一个查询参数(getAction
),所以我们可以在 doGet(e)
函数上检测到它。在那里我们检查该参数,我们得到了 return 一个 JavaScript 内容。
默认情况下禁用按钮,我添加了一个小代码,以便在脚本完成加载时启用按钮(它是异步的,因此可能需要一些时间才能完全加载)。
此技术还可用于通过获取结果、创建脚本元素并手动添加内容来动态添加脚本标签。