向 Google 表格提交表单时出错,导致 CORS 错误
Posted
技术标签:
【中文标题】向 Google 表格提交表单时出错,导致 CORS 错误【英文标题】:Error submitting form to Google Sheets which causes a CORS error 【发布时间】:2021-07-07 05:02:17 【问题描述】:我目前有一个在 localhost 上运行的表单,该表单将数据提交到 Google 表格的脚本以将其发布到电子表格中。每次我提交表单时,我都会收到此错误: 跨域请求被阻止:同源策略不允许在 https://script.google.com/macros/s/xxxxxxxxx/exec 读取远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)
在 Google 脚本方面,我已经将部署设置为:执行设置为 Me,谁有权访问设置为 Anyone。
这是用于提交表单的 javascript 代码。
form.addEventListener('submit', (e) =>
e.preventDefault();
console.log("form has been submitted!");
fetch('https://script.google.com/macros/s/xxxxxxxxx/exec',
method: 'POST',
mode: 'cors',
body: new FormData(form)
)
.then(response =>
if(response.ok)
console.log('Success!', response);
else
console.log(response);
alert("Ohhh noooo!! ERROR please try again response: " + response.status);
)
.catch(error =>
console.log("Error!!" + error);
console.error('Error!', error.message);
alert('BEEP BOOP: there is an error, please try again');
);
这是 Google 表格的脚本
function intialSetup()
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
scriptProp.setProperty('key', activeSpreadsheet.getId());
function doPost(e)
var lock = LockService.getScriptLock();
lock.tryLock(10000);
try
var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'));
var sheet = doc.getSheetByName(sheetName);
var json = JSON.stringify(e.postData);
var obj = JSON.parse(json);
var task = obj["task"];
// spreadsheet tab names
switch (task)
case "Tech Trimming":
specificTab(task, obj["tray_number"], obj["name"], obj["qrCodeArea"].split("\n"));
break;
default:
Logger.log("option does not exist");
return ContentService
.createTextOutput(JSON.stringify( 'result': 'success', 'row': nextRow ))
.setMimeType(ContentService.MimeType.JSON)
catch (e)
return ContentService
.createTextOutput(JSON.stringify( 'result': 'error', 'error': e ))
.setMimeType(ContentService.MimeType.JSON)
finally
lock.releaseLock();
function specificTab(task, trayNum, techName, impressions)
var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var subSheetName = spreadSheet.getSheetByName(task);
var date = getDate();
var lastRow = subSheetName.getLastRow();
for (var i = 0; i < impressions.length - 1; i++)
subSheetName.getRange(lastRow + 1, 1).setValue(date);
subSheetName.getRange(lastRow + 1, 2).setValue(trayNum);
subSheetName.getRange(lastRow + 1, 3).setValue(techName);
subSheetName.getRange(lastRow + 1, 4).setValue(impressions[i]);
lastRow++;
在 Google Scripts 的执行选项卡上,如果您提交,所有执行都会显示为失败。
几个月前,在我的另一台计算机上,一切似乎都运行良好。正如我可以提交表格,然后它会毫无问题地发布到电子表格中。我目前使用的计算机似乎给了我这些问题。我无法测试这个理论,因为我现在没有另一台电脑。
我已将此表单部署到 vercel,但似乎没有解决问题。
【问题讨论】:
【参考方案1】:完全使用纯文本进行通信以避免 CORS 错误
这意味着每当您向网络应用程序发送 POST 请求时,JSON.stringify()
您的所有数据,然后是 JSON.parse()
(如果相关)。您可能还需要将标题设置为"Content-Type": "text/plain"
。
也就是说,不要直接发送FormData
对象,确保客户端和Web应用程序之间的所有通信都以纯文本进行,然后在另一端解码信息。
在 Apps 脚本方面,确保您使用的是:
ContentService.createTextOutput(JSON.stringify( 'result': 'success', 'row': nextRow ));
.setMimeType(ContentService.MimeType.TEXT) // Maybe you can omit this line.
而不是:
ContentService.createTextOutput(JSON.stringify( 'result': 'success', 'row': nextRow ));
.setMimeType(ContentService.MimeType.JSON)
回复您的doPost
。最好也使用doGet
来执行此操作。
no-cors
如果不需要来自 POST 请求的响应(尽管我想您会想要它),您可以将请求模式设置为 mode: 'no-cors'
,但是您的客户端将无法访问有关响应的任何信息。
CORS 代理
您还可以设置(或使用第三方服务)代理服务器,该服务器将在后端发出请求,并允许向您的客户端发出 CORS 请求。
参考
Content Service【讨论】:
这成功了!非常感谢你。您关于 CORS 的建议解决了我的问题。我现在需要修改我的脚本端以解析文本以使其再次按预期工作。以上是关于向 Google 表格提交表单时出错,导致 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章
在 Google Apps 脚本中提交 HTML 表单时如何发送地理定位和输入