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

使用Google Apps Script提交React表单数据至Google Sheet时如何避免重定向

解决React表单提交到Google Sheet后重定向到JSON页面的问题

核心原因

使用原生表单的action和method属性提交时,浏览器会默认跳转到目标端点,从而显示Google Apps Script返回的JSON响应。解决思路是采用异步AJAX提交,阻止表单默认跳转行为。


步骤1:修改React表单组件

替换原生表单提交逻辑,使用fetch实现异步提交,并添加状态提示:

import React, { useState } from "react";

export default function Form(props) {
  const [data, setData] = useState({
    name: "",
    company: "",
    service: "",
    contact: "",
    technician: "",
  });
  const [submitting, setSubmitting] = useState(false);
  const [submitStatus, setSubmitStatus] = useState(null);

  const { name, company, service, contact, technician } = data;

  const handleChange = (e) => {
    setData({ ...data, [e.target.name]: e.target.value });
  };

  const handleSubmit = async (e) => {
    e.preventDefault(); // 阻止默认表单跳转行为
    setSubmitting(true);
    setSubmitStatus(null);

    try {
      const response = await fetch("<你的Google脚本API端点>", {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        body: new URLSearchParams(data).toString(), // 格式化表单数据为URL编码格式
      });

      const result = await response.json();
      if (result.result === "success") {
        setSubmitStatus("提交成功!我们会尽快联系你。");
        // 重置表单
        setData({
          name: "",
          company: "",
          service: "",
          contact: "",
          technician: "",
        });
      } else {
        throw new Error(result.error);
      }
    } catch (err) {
      setSubmitStatus(`提交失败:${err.message}`);
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="form-container">
      <form onSubmit={handleSubmit}>
        <div className="form-group">
          <h3 className="form-header">Service Inquiry</h3>
          <label className="input-label">Name:</label>
          <textarea
            type="text"
            name="name"
            value={name}
            onChange={handleChange}
            required
            className="input"
            rows="1"
            disabled={submitting}
          ></textarea>
        </div>

        <div className="form-group">
          <label className="input-label">Company Name:</label>
          <textarea
            type="text"
            name="company"
            value={company}
            onChange={handleChange}
            required
            className="input"
            rows="1"
            disabled={submitting}
          ></textarea>
        </div>
        <div className="form-group">
          <label className="input-label">What can we do for you?</label>

          <textarea
            type="text"
            name="service"
            value={service}
            onChange={handleChange}
            required
            className="input"
            rows="5"
            cols="50"
            disabled={submitting}
          ></textarea>
        </div>
        <div className="form-group">
          <label className="input-label">
            Please leave a way for us to contact you:
          </label>
          <textarea
            type="text"
            name="contact"
            value={contact}
            onChange={handleChange}
            placeholder="Email or Phone"
            className="input"
            rows="1"
            disabled={submitting}
          ></textarea>
        </div>
        <div className="form-group">
          <label className="input-label">Request Specific Technician:</label>
          <textarea
            type="text"
            name="technician"
            value={technician}
            onChange={handleChange}
            className="input"
            rows="1"
            placeholder="*optional"
            disabled={submitting}
          ></textarea>

          <p className="footnote">
            *if you would like a specific technician, please specify
          </p>
          <input 
            type="submit" 
            value={submitting ? "提交中..." : "Send"} 
            className="submit-button" 
            disabled={submitting}
          />
          {submitStatus && <p className={`status ${submitStatus.includes("成功") ? "success" : "error"}`}>{submitStatus}</p>}
        </div>
      </form>
    </div>
  );
}

关键修改点:

  • 添加onSubmit事件处理函数handleSubmit,调用e.preventDefault()阻止默认跳转
  • 使用fetch异步发送POST请求,将表单数据格式化为URL编码格式(适配Google Apps Script的e.parameter解析)
  • 添加提交状态(加载中、成功/失败提示),提升用户体验
  • 提交时禁用表单控件,防止重复提交

步骤2:优化Google Apps Script(可选)

为了避免CORS问题,可以在返回响应时添加CORS头部,修改doPost函数的返回部分:

// ... 原有代码不变 ...

try {
  // ... 原有数据写入逻辑不变 ...

  return ContentService
    .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow }))
    .setMimeType(ContentService.MimeType.JSON)
    .setHeader('Access-Control-Allow-Origin', '*') // 添加CORS头部
    .setHeader('Access-Control-Allow-Methods', 'POST')
    .setHeader('Access-Control-Allow-Headers', 'Content-Type')
}

catch (e) {
  return ContentService
    .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
    .setMimeType(ContentService.MimeType.JSON)
    .setHeader('Access-Control-Allow-Origin', '*') // 错误响应也添加CORS头部
}

// ... 原有代码不变 ...

说明:

  • 若你的网站部署在特定域名,可将*替换为你的域名(如https://yourdomain.com),提升安全性
  • 原有ContentService的使用无需替换,异步请求可以正常接收其返回的JSON响应

内容的提问来源于stack exchange,提问作者Steven Dew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:35:11