纯JS无刷新提交表单至Google Sheet(Apps Script doGet)数据为空问题
问题排查:无刷新提交表单至Google Sheet失败(返回成功但无数据写入)
直接提交表单时数据可正常写入Google Sheet,但通过JavaScript无刷新提交后,虽收到{"result":"success","data":[null,null,null,null]}的成功响应,却没有数据写入Sheet。采用的是Google Apps Script的doGet方法。
现有代码
Google Apps Script 代码
var SHEET_KEY = '1IW8xdxivaSALFgUxGs9SIwAe07S6ZENEx-Ekr8l8aqU' var SHEET_NAME = 'page1' function doGet(e) { var lock = LockService.getPublicLock() try { var doc = SpreadsheetApp.openById(SHEET_KEY) var sheet = doc.getSheetByName(SHEET_NAME) var data = [] data = [ e.parameter['pr_name'], e.parameter['ing'], e.parameter['gramm'], e.parameter['class_p'], ] sheet.getRange(sheet.getLastRow() + 1, 1, 1, data.length).setValues([data]) return ContentService.createTextOutput( JSON.stringify({ result: 'success' }) ).setMimeType(ContentService.MimeType.JSON) } catch (e) { return ContentService.createTextOutput( JSON.stringify({ result: 'error', error: e }) ).setMimeType(ContentService.MimeType.JSON) } finally { lock.releaseLock() } }
HTML 表单代码
<form class="gform" method="GET" action="https://script.google.com/macros/s/AKfycbxoDeBDNJtnPkNxsMmWwIAT7ojRnxgzWBH-wHQnCmfWD6a-gsOdPrSopQ_fK3GJVtlw3w/exec" > <input type="text" name="pr_name" > <input type="text" name="ing"> <input type="text" name="gramm"> <input type="text" name="class_p"> <input type="submit"> </form>
JavaScript 提交代码
let form = document.querySelector('form'); form.addEventListener('submit', function(evt) { evt.preventDefault(); sendData(); }); function sendData() { const XHR = new XMLHttpRequest(); const FD = new FormData( form ); XHR.addEventListener( "load", function(event) { alert( event.target.responseText ); } ); XHR.addEventListener( "error", function( event ) { alert( 'Oops! Something went wrong.' ); } ); XHR.open( "GET", "https://script.google.com/macros/s/AKfycbxoDeBDNJtnPkNxsMmWwIAT7ojRnxgzWBH-wHQnCmfWD6a-gsOdPrSopQ_fK3GJVtlw3w/exec" ); XHR.send( FD ); }
问题原因
核心问题是GET请求与FormData的不兼容:
- 直接提交表单时,浏览器会自动将表单数据拼接成URL查询参数(如
?pr_name=xxx&ing=xxx...),doGet方法通过e.parameter能正常读取这些参数。 - 使用XMLHttpRequest发送GET请求并传递FormData时,浏览器不会自动将FormData转为URL查询参数,而是将请求体设为FormData编码格式,但
doGet方法只能读取URL查询参数,无法解析请求体内容,导致e.parameter中所有字段为null,最终写入Sheet的是空数据。
解决方案
以下两种方案任选其一即可:
方案1:改用POST请求(推荐)
这种方式更符合AJAX提交规范,也避免URL长度限制。
修改JavaScript代码
将请求方法改为POST:
function sendData() { const XHR = new XMLHttpRequest(); const FD = new FormData( form ); XHR.addEventListener( "load", function(event) { alert( event.target.responseText ); } ); XHR.addEventListener( "error", function( event ) { alert( 'Oops! Something went wrong.' ); } ); // 改为POST请求 XHR.open( "POST", "https://script.google.com/macros/s/AKfycbxoDeBDNJtnPkNxsMmWwIAT7ojRnxgzWBH-wHQnCmfWD6a-gsOdPrSopQ_fK3GJVtlw3w/exec" ); XHR.send( FD ); }
修改Google Apps Script代码
将doGet改为doPost(逻辑不变,仅方法名替换):
var SHEET_KEY = '1IW8xdxivaSALFgUxGs9SIwAe07S6ZENEx-Ekr8l8aqU' var SHEET_NAME = 'page1' // 将doGet改为doPost function doPost(e) { var lock = LockService.getPublicLock() try { var doc = SpreadsheetApp.openById(SHEET_KEY) var sheet = doc.getSheetByName(SHEET_NAME) var data = [] data = [ e.parameter['pr_name'], e.parameter['ing'], e.parameter['gramm'], e.parameter['class_p'], ] sheet.getRange(sheet.getLastRow() + 1, 1, 1, data.length).setValues([data]) return ContentService.createTextOutput( JSON.stringify({ result: 'success' }) ).setMimeType(ContentService.MimeType.JSON) } catch (e) { return ContentService.createTextOutput( JSON.stringify({ result: 'error', error: e }) ).setMimeType(ContentService.MimeType.JSON) } finally { lock.releaseLock() } }
注意:修改Apps Script后需重新部署新版本,确保部署时执行权限设置为「任何人,甚至匿名」。
方案2:保持GET请求,手动转换参数格式
如果坚持使用GET请求,需将FormData手动转为URL查询参数并附加到URL后:
修改JavaScript代码
function sendData() { const XHR = new XMLHttpRequest(); const FD = new FormData( form ); // 将FormData转为URL查询参数 const params = new URLSearchParams(FD); XHR.addEventListener( "load", function(event) { alert( event.target.responseText ); } ); XHR.addEventListener( "error", function( event ) { alert( 'Oops! Something went wrong.' ); } ); // 将查询参数附加到URL末尾 XHR.open( "GET", "https://script.google.com/macros/s/AKfycbxoDeBDNJtnPkNxsMmWwIAT7ojRnxgzWBH-wHQnCmfWD6a-gsOdPrSopQ_fK3GJVtlw3w/exec?" + params.toString() ); XHR.send(); // 不再传递FormData }
此方案下,Google Apps Script的doGet方法无需修改,参数会通过URL查询字符串传递,e.parameter可正常读取值。
内容的提问来源于stack exchange,提问作者aaadraniki
相关产品推荐
相关产品推荐

