独立Web App可URL填充表单,嵌入Iframe/Google Sites失效求助
问题:嵌入Iframe/Google Sites后,Google Apps Script Web App的URL参数填充表单功能失效
问题背景
开发了一个Google Apps Script Web App表单,核心需求:
- 通过URL参数填充指定表单字段,字段仅展示内容不可编辑
- 提交表单时用UUID标识提交记录
独立测试阶段,类似 https://script.google.com/macros/s/xxx/dev?fn=bob 的链接可正常将值填入fn字段。但为移除Google的*"This application was created by another user, not by Google.Terms of Service"*提示,将Web App嵌入Iframe或关联至Google Sites后,URL参数填充表单的功能完全失效。
当前代码
1. Server端脚本(Code.gs)
function doGet() { return HtmlService.createTemplateFromFile("page").evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL); } function userClicked(userInfo){ const url = "https://docs.google.com/spreadsheets/d/1-7D4bXhm1Yx0ekRUmrwr8fTsdQ0dLtMI4gYG-THPUdk/edit#gid=0"; const ss = SpreadsheetApp.openByUrl(url); const ws = ss.getSheetByName("data"); ws.appendRow([userInfo.firstName,userInfo.lastName,userInfo.app,new Date()]) } function include(filename){ return HtmlService.createHtmlOutputFromFile(filename).getContent(); }
2. Client端表单交互脚本(HTML)
<script> document.addEventListener('DOMContentLoaded', function() { var elems = document.querySelectorAll('select'); var instances = M.FormSelect.init(elems); }); document.getElementById("btn").addEventListener("click",doStuff); function doStuff(){ const userInfo = {}; userInfo.firstName = document.getElementById("fn").value; userInfo.lastName = document.getElementById("ln").value; userInfo.app = document.getElementById("app").value; google.script.run.userClicked(userInfo); document.getElementById("fn").value = ""; document.getElementById("ln").value = ""; var myApp = document.getElementById("app"); myApp.selectedIndex = 0; M.FormSelect.init(myApp); } </script>
3. URL参数填充脚本(HTML)
<script> google.script.url.getLocation(function(location){ document.getElementById('fn').value = location.parameters.fn[0] document.getElementById('ln').value = location.parameters.ln[0] }) </script>
解决方案建议
1. 替换google.script.url.getLocation为纯前端URL解析
嵌入场景下,google.script.url.getLocation无法正确获取参数,改用原生JS解析URL:
<script> document.addEventListener('DOMContentLoaded', function() { const urlParams = new URLSearchParams(window.location.search); const fnValue = urlParams.get('fn'); const lnValue = urlParams.get('ln'); if(fnValue) { const fnField = document.getElementById('fn'); fnField.value = fnValue; fnField.disabled = true; // 设置字段不可编辑 } if(lnValue) { const lnField = document.getElementById('ln'); lnField.value = lnValue; lnField.disabled = true; } }); </script>
2. 确保嵌入载体传递正确参数
- 自定义网站Iframe:直接在
src中拼接参数,例如:<iframe src="https://script.google.com/macros/s/xxx/dev?fn=bob&ln=smith" width="600" height="400"></iframe> - Google Sites:添加Web App部件时,在部件设置的URL中直接带上参数即可。
3. 实现UUID提交功能
修改客户端提交函数生成UUID,同时更新服务端写入逻辑:
// 客户端doStuff函数修改 function doStuff(){ // 生成UUID function generateUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } const userInfo = {}; userInfo.firstName = document.getElementById("fn").value; userInfo.lastName = document.getElementById("ln").value; userInfo.app = document.getElementById("app").value; userInfo.uuid = generateUUID(); // 新增UUID字段 google.script.run.userClicked(userInfo); // 重置表单逻辑不变... }
// 服务端userClicked函数修改 function userClicked(userInfo){ const url = "https://docs.google.com/spreadsheets/d/1-7D4bXhm1Yx0ekRUmrwr8fTsdQ0dLtMI4gYG-THPUdk/edit#gid=0"; const ss = SpreadsheetApp.openByUrl(url); const ws = ss.getSheetByName("data"); // 新增UUID列写入 ws.appendRow([userInfo.firstName,userInfo.lastName,userInfo.app,userInfo.uuid,new Date()]) }
4. 验证权限与X-Frame设置
确认doGet函数已设置setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)(当前代码已包含);Web App部署权限设为“任何人,甚至匿名用户”(若允许匿名访问),避免嵌入时出现权限拦截。
内容的提问来源于stack exchange,提问作者Matthew Gibbon
相关产品推荐
相关产品推荐

