Google Apps Script中Materialize表单添加name="action"属性报错排查
name="action"导致的提交错误解析 我来帮你理清这个问题的来龙去脉,你遇到的情况其实是Google Apps Script(GAS)表单处理的特殊规则和Materialize按钮属性冲突导致的。
1. name="action"的常规作用
在标准HTML里,给提交按钮设置name="action"是为了区分同一表单内的多个提交操作。比如一个表单有“保存”和“删除”两个按钮,你可以给它们都加name="action",然后分别设置value="save"和value="delete",后端就能通过读取action参数的值,判断用户触发了哪个操作。
2. GAS里报错的核心原因
Google Apps Script对表单有一套内置的处理逻辑:当表单中存在name="action"的控件时,GAS会自动劫持表单的默认提交行为,它会尝试直接调用服务端与action值同名的函数(而不是你写的onsubmit事件里的readFile)。
这个过程中,GAS会试图用iframe加载函数执行的结果,但由于Google的Content Security Policy(CSP)限制(指令为frame-ancestors 'self'),外部页面无法嵌入这个iframe,最终就抛出了你看到的:
Refused to frame 'https://xxxxxxx-script.googleusercontent.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'".
同时因为GAS找不到对应action值的服务端函数(你只写了upload),所以会伴随HTTP 500错误,自然也不会调用你的upload函数。
3. 快速解决办法
方案一:直接移除name="action"
Materialize的按钮样式完全不需要name="action"属性,删掉它之后,你的自定义onsubmit事件就能正常触发,google.script.run.upload也会被正确调用:
<button class="btn waves-effect waves-light" type="submit" id="btn">Submit<i class="material-icons right">send</i></button>
方案二:换用其他name值(如果需要区分按钮)
如果你确实需要在表单里设置多个提交按钮,换个name值就行,比如name="submitAction":
<button class="btn waves-effect waves-light" type="submit" name="submitAction" value="upload">Submit<i class="material-icons right">send</i></button>
然后在你的readFile函数里读取这个值,再传给服务端:
function readFile(formObject) { const submitAction = formObject.submitAction.value; google.script.run.upload({formData: formObject, action: submitAction}); }
服务端的upload函数可以根据这个参数做不同处理:
function upload(payload) { Logger.log('upload called with action: ' + payload.action); Logger.log('form data: ' + payload.formData); }
内容的提问来源于stack exchange,提问作者kkas

