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

基于Google Sheet的Apps Script Web App提交后返回403禁止错误

解决Google Apps Script Web App提交后返回403 Forbidden且不显示成功消息的问题

我用Google Sheet的Apps Script搭建了一个Web App,它能获取用户位置并成功向表格插入新行,但提交表单完成插入后,不会返回成功消息,反而弹出Forbidden Error 403。我已经清除浏览器缓存、尝试过不同浏览器和设备,问题依然存在。

现有GS文件代码

const sheetName = 'Sheet1'
const scriptProp = PropertiesService.getScriptProperties()

function initialSetup () {
const activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
scriptProp.setProperty('key', activeSpreadsheet.getId())
}

function doPost (e) {
const lock = LockService.getScriptLock()
lock.tryLock(10000)

try {
const doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
const sheet = doc.getSheetByName(sheetName)

const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
const nextRow = sheet.getLastRow() + 1

const newRow = headers.map(function(header) {
  return header === 'Date' ? new Date() : e.parameter[header]
})

sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])

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 doGet(e) {
const userEmail = Session.getActiveUser().getEmail();
var htmlOutput =  HtmlService.createTemplateFromFile('Form');
htmlOutput.email = userEmail;
return htmlOutput.evaluate();
}

现有HTML文件代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-16">
<title>Google Sheet Form</title>
<style>
  form {...
</style>
<script>
  function getLocation() {
    // Check if the browser supports geolocation
    if (navigator.geolocation) {
      // Get the current position of the user
      navigator.geolocation.getCurrentPosition(showPosition);
    } else {
      alert("Geolocation is not supported by this browser.");
    }
  }

  function showPosition(position) {
    // Get the latitude and longitude values from the geolocation data
    var latitude = position.coords.latitude;
    var longitude = position.coords.longitude;
    // Populate the input field with the latitude and longitude values
    document.getElementById("Latitude").value = latitude;
    document.getElementById("Longitude").value = longitude;
  }

  // Function to show the success message
  function showSuccessMessage() {
    const successMessage = document.getElementById('successMessage');
    successMessage.style.display = 'block';
  }

  const responseText = '{"result": "success"}'; // Replace this with the actual response
  const response = JSON.parse(responseText);

  if (response.result === 'success') {
    // Display the success message to the user
    showSuccessMessage();
  }

</script>
</head>
<body>
<form 
action="..." method="post">
  <span>Logged In: <?= email ?></span>
 <p> <input size="20" name="Email" type="email" 
placeholder="Email" required value="<?= email ?>" readonly> </p>
 <p> <input size="20" type="text" id="Latitude" name="Latitude" 
placeholder="Latitude"readonly> </p>
 <p> <input size="20" type="text" id="Longitude" name="Longitude" 
placeholder="Longitude"readonly> </p>
 <p> <button size="20" type="button" onclick="getLocation()">Get 
Location</button> </p>
 <p> <button size="20" type="submit">Sign In/Sign Out</button> 
</p>

<!-- Add a div to display the success message -->
  <div id="successMessage" style="display: none;">Form submitted 
successfully!</div>

  <!-- Add a div to display the error message -->
  <div id="errorMessage" style="display: none;">An error 
occurred. Please try again.</div>
</form>
</body>
</html>

问题根源分析

  1. 403 Forbidden错误:HTML表单的action属性是占位符"...",未填写正确的Web App部署URL,导致提交请求地址无效;同时Web App部署权限可能未配置正确,拒绝了外部请求。
  2. 成功消息不显示:当前HTML硬编码了模拟响应,未实际接收doPost返回的真实数据,且表单默认同步提交会直接跳转页面,无法执行后续消息显示逻辑。

修复步骤

1. 修正Web App部署配置

重新部署Web App,确保:

  • 执行权限选择**「任何人,甚至匿名用户」(无需登录限制)或「任何人」**(需用户登录Google账号)
  • 复制部署后生成的Web App URL,后续用于表单提交地址

2. 重写HTML实现异步提交与响应处理

将表单改为AJAX异步提交,避免页面跳转,同时接收doPost返回的JSON响应并显示对应消息:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Google Sheet Form</title>
<style>
  form {
    margin: 20px;
    padding: 20px;
    border: 1px solid #ccc;
    border-radius: 8px;
  }
  #successMessage {
    color: green;
    margin-top: 15px;
  }
  #errorMessage {
    color: red;
    margin-top: 15px;
  }
</style>
<script>
  function getLocation() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(showPosition);
    } else {
      alert("当前浏览器不支持地理定位");
    }
  }

  function showPosition(position) {
    document.getElementById("Latitude").value = position.coords.latitude;
    document.getElementById("Longitude").value = position.coords.longitude;
  }

  // 处理表单提交
  function handleSubmit(event) {
    event.preventDefault();
    const formData = new FormData(event.target);
    // 替换为你的Web App部署URL
    const webAppUrl = "你的Web App部署URL";

    fetch(webAppUrl, {
      method: 'POST',
      body: formData
    })
    .then(res => res.json())
    .then(data => {
      const successEl = document.getElementById('successMessage');
      const errorEl = document.getElementById('errorMessage');
      if (data.result === 'success') {
        successEl.style.display = 'block';
        errorEl.style.display = 'none';
        event.target.reset();
      } else {
        errorEl.style.display = 'block';
        successEl.style.display = 'none';
        console.error('提交失败:', data.error);
      }
    })
    .catch(err => {
      document.getElementById('errorMessage').style.display = 'block';
      document.getElementById('successMessage').style.display = 'none';
      console.error('请求异常:', err);
    });
  }

  // 绑定提交事件
  document.addEventListener('DOMContentLoaded', () => {
    document.querySelector('form').addEventListener('submit', handleSubmit);
  });
</script>
</head>
<body>
<form>
  <span>已登录: <?= email ?></span>
  <p> 
    <input size="20" name="Email" type="email" placeholder="邮箱" required value="<?= email ?>" readonly> 
  </p>
  <p> 
    <input size="20" type="text" id="Latitude" name="Latitude" placeholder="纬度" readonly> 
  </p>
  <p> 
    <input size="20" type="text" id="Longitude" name="Longitude" placeholder="经度" readonly> 
  </p>
  <p> 
    <button size="20" type="button" onclick="getLocation()">获取位置</button> 
  </p>
  <p> 
    <button size="20" type="submit">签到/签退</button> 
  </p>

  <div id="successMessage" style="display: none;">表单提交成功!</div>
  <div id="errorMessage" style="display: none;">提交失败,请重试。</div>
</form>
</body>
</html>

3. 优化GS代码(可选)

添加必填字段验证,避免空数据提交:

// 在doPost的try块开头添加
if (!e.parameter.Email || !e.parameter.Latitude || !e.parameter.Longitude) {
  throw new Error('缺少必填字段:邮箱/纬度/经度');
}

注意事项

  • 每次修改代码后,必须重新部署Web App并更新HTML中的webAppUrl(如果部署生成了新URL)
  • 若需限制特定用户访问,可在doPost中添加邮箱白名单验证逻辑

内容的提问来源于stack exchange,提问作者Pieter le Roux

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:10:57