HTTP POST到Google Sheets(Apps Script)无法导入JSON请求体内容求助
问题描述
我开发了一款Web应用,通过HTTP POST和Google Apps Script向Google Sheets提交订单信息,但无法从请求体的JSON中提取数据并写入表格。尝试了三种方法:
- 方法1(XMLHttpRequest):注释Content-type设置时,postData显示为FileUpload;启用该设置后无输出。
- 方法2(fetch):结果与方法1类似,postData仍为FileUpload类型。
- 方法3(FormData):可获取参数但内容长度过大,不够高效。
Google Apps Script的doPost函数尝试解析请求体内容写入单元格,但未能成功。通过JSON.stringify(e)输出可见,postData的contents中存在正确的JSON数据,但无法提取firstName和lastName写入对应单元格。此外还存在两个疑问:
- fetch是否比XMLHttpRequest更合适?
- postData为FileUpload类型是否会影响数据解析?
相关代码
方法1代码:
function method1() { var xml = new XMLHttpRequest(); var data = JSON.stringify({ firstName: "Jay", lastName: "Smith" }); xml.open("POST", url, true); /* xml.setRequestHeader("Content-type", "application/json"); */ xml.onreadystatechange = function () { if (xml.readyState === 4 && xml.status === 200) { alert(xml.responseText); } }; xml.send(data); }
方法2代码:
function method2() { const body = { firstName: "Jay", lastName: "Smith", }; const options = { method: "POST", body: JSON.stringify(body), }; fetch(url, options).then((res) => res.json()); }
方法3代码:
function method3() { const formData = new FormData(); formData.append("firstName", "Jay"); formData.append("lastName", "Smith"); fetch(url, { method: "POST", body: formData, }).then((res) => res.json()); }
Google Apps Script的doPost函数:
function doPost(e) { const sheet = SpreadsheetApp.openById(SHEETID).getSheetByName('Testing Inputs'); sheet.getRange(3,1).setValue(e); // To display POST output const data = JSON.parse(request.postData.contents) sheet.getRange(5,1).setValue(data['firstName']) // Not writing "Jay"? sheet.getRange(5,2).setValue(data['lastName']) // Not writing "Smith"? }
JSON.stringify(e)输出:
{"parameter":{},"postData":{"contents":"{\"firstName\":\"Jay\",\"lastName\":\"Smith\"}","length":38,"name":"postData","type":"text/plain"},"parameters":{},"contentLength":38,"queryString":"","contextPath":""}
解决方案
1. 修复doPost函数的核心错误
你的doPost函数中使用了未定义的request变量,应该用传入的参数e来访问postData。同时需要返回合法的响应,避免请求超时。修正后的代码:
function doPost(e) { const sheet = SpreadsheetApp.openById(SHEETID).getSheetByName('Testing Inputs'); // 解析请求体中的JSON数据 const data = JSON.parse(e.postData.contents); // 将数据写入指定单元格 sheet.getRange(5, 1).setValue(data.firstName); sheet.getRange(5, 2).setValue(data.lastName); // 返回成功响应 return ContentService.createTextOutput(JSON.stringify({ status: "success" })) .setMimeType(ContentService.MimeType.JSON); }
2. 修正前端请求的Content-Type设置
发送JSON格式的POST请求时,必须显式设置Content-Type: application/json,否则Google Apps Script会将请求体识别为文件上传(FileUpload类型),导致解析异常。
修正后的方法1(XMLHttpRequest):
function method1() { var xml = new XMLHttpRequest(); var data = JSON.stringify({ firstName: "Jay", lastName: "Smith" }); xml.open("POST", url, true); // 必须添加Content-Type头 xml.setRequestHeader("Content-type", "application/json"); xml.onreadystatechange = function () { if (xml.readyState === 4 && xml.status === 200) { alert(xml.responseText); } }; xml.send(data); }
修正后的方法2(fetch):
function method2() { const body = { firstName: "Jay", lastName: "Smith", }; const options = { method: "POST", headers: { "Content-Type": "application/json", // 添加Content-Type头 }, body: JSON.stringify(body), }; fetch(url, options) .then((res) => res.json()) .then(result => console.log("提交成功:", result)) .catch(err => console.error("提交失败:", err)); }
3. 疑问解答
- fetch是否比XMLHttpRequest更合适?
是的。fetch是现代浏览器提供的原生API,基于Promise实现,语法更简洁直观,避免了XMLHttpRequest的回调嵌套问题,代码可读性和可维护性更高,是当前推荐的HTTP请求方式。 - postData为FileUpload类型是否会影响数据解析?
会。当请求未设置正确的Content-Type时,Google Apps Script会默认将请求体当作文件上传处理,标记为FileUpload类型。虽然仍能从postData.contents读取原始内容,但这不符合JSON请求的标准处理流程,容易引发解析错误,必须通过设置正确的Content-Type来避免这种情况。
内容的提问来源于stack exchange,提问作者FrozenXeno
相关产品推荐
相关产品推荐

