如何在Google Apps Script Web应用沙箱的JavaScript中获取URL查询参数?
解决Google Apps Script Web应用中URL参数获取的问题
问题根源
你碰到的这个情况是Google Apps Script Web应用的默认沙箱机制导致的:默认情况下,Web应用是以IFRAME模式运行的,你的前端页面其实是嵌入在一个googleusercontent.com域名的iframe里面,所以window.location拿到的是这个iframe的内部URL,而不是用户地址栏里显示的真实Web应用地址。
解决方案1:前端直接获取真实URL并解析参数
既然页面是嵌入在iframe里的,我们可以直接获取父页面的URL(也就是用户地址栏里的真实地址),然后解析参数:
修改你的OnLoad函数:
function OnLoad(){ // 获取父页面的真实URL(仅IFRAME模式下有效) const actualUrl = window.parent.location.href; alert(actualUrl); // 封装一个解析URL参数的工具函数 function getUrlParam(paramName) { const searchParams = new URLSearchParams(new URL(actualUrl).search); return searchParams.get(paramName); } // 拿到你需要的id参数 const targetId = getUrlParam('id'); alert(`获取到的ID参数:${targetId}`); }
小提示:如果你的Web应用部署时选择了NATIVE模式(部署设置里的“网页应用的执行方式”相关选项),那么页面不会被嵌入iframe,直接用
window.location.href就能拿到真实URL,不需要用window.parent。
解决方案2:服务器端直接传递参数到HTML模板(更可靠)
既然你已经在doGet(e)函数里拿到了id参数,完全可以直接把这个参数注入到HTML模板中,前端直接使用即可,不用再自己解析URL,也避开了沙箱的问题。
步骤1:修改doGet和loadClassView函数
function doGet(e){ const param1 = e.parameters.v; const param2 = e.parameters.id; if(param1 == "form"){ return loadForm(); } else if(param1 == "class") { // 把id参数传递给loadClassView return loadClassView(param2); } else { const tmp = HtmlService.createTemplateFromFile("home"); tmp.baseUrlToSend = baseURL; return tmp.evaluate(); } } function loadClassView(pageId) { // 创建模板并注入id参数 const template = HtmlService.createTemplateFromFile("classView"); template.targetId = pageId; return template.evaluate(); }
步骤2:在HTML模板中使用参数
假设你的类视图页面是classView.html,在页面脚本中直接使用模板注入的参数:
<script> function OnLoad(){ // 直接使用服务器传递过来的ID const id = <?= targetId ?>; alert(`服务器传递的ID:${id}`); } // 页面加载时执行 window.onload = OnLoad; </script>
关于多用户的疑问
你不用担心服务器会搞混不同用户的参数——doGet(e)函数是每个HTTP请求独立执行的,每个用户访问不同的URL时,e.parameters对应的是当前请求的URL参数,和其他用户的请求完全隔离,服务器会分别处理每个请求并返回对应参数的页面。
内容的提问来源于stack exchange,提问作者John Kane




