You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义HTML表单提交至Google Sheet/Drive失败,遇CORS错误求助

解决Google Apps Script Web App的CORS错误及文件上传问题

核心问题原因

浏览器发送POST请求前会先发起OPTIONS预检请求,你的Google Apps Script未处理该请求,也未返回CORS允许头,导致浏览器拦截响应。即便权限设为“任何人”,也需要明确处理预检请求并配置正确的响应头。


步骤1:修正Google Apps Script代码(处理CORS与文件上传)

更新doPost函数,添加OPTIONS请求处理逻辑,并正确解析表单上传的文件:

function doPost(e) {
  // 处理CORS预检请求
  if (e.method === 'OPTIONS') {
    return ContentService.createTextOutput('')
      .setMimeType(ContentService.MimeType.TEXT)
      .setHeaders({
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'
      });
  }

  try {
    // 提取表单文本字段
    const email = e.parameters.email[0];
    const name = e.parameters.name[0];

    // 提取上传的文件(FormData上传的文件以Blob形式存在)
    const stlBlob = e.parameters.stlFile[0];
    const idCardBlob = e.parameters.idCardFile[0];

    // 写入Google Sheet
    const targetSheet = SpreadsheetApp.openById('你的Google Sheet ID')
      .getSheetByName('表单数据'); // 替换为你的工作表名称
    targetSheet.appendRow([email, name, new Date()]);

    // 保存文件到Google Drive
    const targetFolder = DriveApp.getFolderById('你的Drive文件夹ID');
    // 保存STL文件
    if (stlBlob) {
      targetFolder.createFile(stlBlob);
    }
    // 保存学生证文件
    if (idCardBlob) {
      targetFolder.createFile(idCardBlob);
    }

    // 返回成功响应(带CORS头)
    return ContentService.createTextOutput(JSON.stringify({
      status: 'success',
      message: '数据与文件已成功保存'
    }))
    .setMimeType(ContentService.MimeType.JSON)
    .setHeaders({ 'Access-Control-Allow-Origin': '*' });

  } catch (err) {
    // 返回错误响应(带CORS头)
    return ContentService.createTextOutput(JSON.stringify({
      status: 'error',
      message: err.toString()
    }))
    .setMimeType(ContentService.MimeType.JSON)
    .setHeaders({ 'Access-Control-Allow-Origin': '*' });
  }
}

步骤2:重新部署Web App(关键配置)

  1. 在Google Apps Script编辑器中,点击部署 > 新部署
  2. 类型选择Web应用
  3. 执行权限:选择任何人,甚至匿名(必须选此项,否则匿名请求会被拦截)
  4. 访问权限:选择任何人
  5. 点击部署,复制生成的Web App URL,替换前端代码中的旧URL

步骤3:修正前端表单提交代码

用FormData处理文件上传,避免设置mode: 'no-cors':

<form id="submissionForm">
  <label>邮箱:<input type="email" name="email" required></label>
  <label>姓名:<input type="text" name="name" required></label>
  <label>STL文件:<input type="file" name="stlFile" accept=".stl" required></label>
  <label>学生证:<input type="file" name="idCardFile" required></label>
  <button type="submit">提交</button>
</form>

<script>
document.getElementById('submissionForm').addEventListener('submit', async (evt) => {
  evt.preventDefault();
  const formData = new FormData(evt.target);

  try {
    const response = await fetch('你的Web App URL', {
      method: 'POST',
      body: formData
    });
    const result = await response.json();
    console.log(result);
    alert('提交成功!');
  } catch (error) {
    console.error('提交失败:', error);
    alert('提交失败,请检查控制台信息或重试');
  }
});
</script>

常见问题排查

  • 若仍报错,检查Web App是否部署了新版本(草稿版本不会生效)
  • 确认Google Sheet和Drive文件夹的权限:脚本执行账号需要拥有编辑权限
  • 不要在fetch中添加mode: 'no-cors',这会导致无法读取响应,还可能隐藏实际错误

内容的提问来源于stack exchange,提问作者Abhishek Sagar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 15:58:18