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

React+Firebase+AstraDB应用提交按钮仅本地可用,跨设备失效求助

问题描述

我开发了一个React应用,通过REST API将表单数据提交至AstraDB,并部署在Firebase域名上。该提交功能在本地localhost:3000及本地网络下的Firebase域名可正常运行,但在iPhone、其他MacBook及安卓设备上点击提交按钮无任何响应。排查过DataStax/AstraDB和Firebase的权限问题但未找到有效方向,且无法在移动设备上通过Chrome调试查看控制台或网络错误信息,寻求技术支持。

使用Node.js版本:v16.1.0

ContactForm.js

import { Checkbox, useCheckboxState } from "pretty-checkbox-react"
import React, { useRef, useState } from "react"
import  { useNavigate  } from 'react-router-dom'
import axios from 'axios'
import emailjs from "@emailjs/browser"

const ContactForm = () => {
    const navigate = useNavigate()
    const [permission, setPermission] = useState(null)
    // const form = useRef()
    const [formData, setFormData] = useState({
        datetime: new Date().toISOString(),
        fName: "",
        lName: "",
        email: "",
        zipCode: "",
        phoneNumber: "",
        services: [],
    })

    const serviceData = [
        "Business Development",
        "Brand Creation",
        "Logo Design",
        "Digital Marketing/Ads",
        "Video/Photography",
        "Social Media/Content",
        "Web Development",
    ]

    const handleSubmit = async (e) => {
        //dont refresh
        e.preventDefault()

        //atra db
        const response = await axios.post("http://localhost:8000/customers", {
            formData,
        })
        const success = response.status === 200
        if (success) {
            console.log("post was successful")
            navigate("/exitpage")
        }

        //clear fromData
        setFormData({
            datetime: "",
            fName: "",
            lName: "",
            email: "",
            zipCode: "",
            PhoneNumber: "",
            services: [],
        })
        //clear checkboxes
        setPermission(false)
    }

    const handleChange = (e) => {
        const value = e.target.value
        const name = e.target.name

        setFormData((prevState) => ({
            ...prevState,
            [name]: value,
        }))
    }

    console.log(formData)

    return (
        <div className="contact-form">
            <div className="container">
                <div className="row">
                    <form validate autocomplete="on" onSubmit={handleSubmit}>
                        <div className="col">
                            <input
                                type="text"
                                value={formData.fName}
                                placeholder="first name"
                                name="fName"
                                onChange={handleChange}
                                required={true}
                            />

                            <input
                                type="text"
                                value={formData.lName}
                                placeholder="last name"
                                name="lName"
                                onChange={handleChange}
                                required={true}
                            />
                        </div>
                        <div className="col">
                            <input
                                type="email"
                                value={formData.email}
                                placeholder="example@email.com"
                                name="email"
                                onChange={handleChange}
                                required={true}
                            />
                        </div>
                        <div className="col">
                            <input
                                type="number"
                                value={formData.zipCode}
                                placeholder="e.g. 66801"
                                name="zipCode"
                                onChange={handleChange}
                                required={true}
                            />
                        </div>
                        <div className="col">
                            <input
                                type="tel"
                                value={formData.phoneNumber}
                                placeholder="e.g. 6203341100"
                                name="phoneNumber"
                                onChange={handleChange}
                                required={true}
                            />
                        </div>
                        <fieldset>
                            <legend>
                                <h1>Please Select Services:</h1>
                            </legend>

                            {serviceData.map((data) => (
                                <div className="col">
                                    <label>
                                        <Checkbox
                                            style={{}}
                                            color="success"
                                            className="service"
                                            animation="rotate"
                                            checked={permission}
                                            plain
                                            icon={<i className="mdi mdi-close" />}
                                            value={data}
                                            name="services"
                                            onChange={(e) => {
                                                if (!formData.services.includes(e.target.value)) {
                                                    setFormData({
                                                        ...formData,
                                                        services: formData.services.concat(e.target.value),
                                                    })
                                                } else {
                                                    setFormData({
                                                        ...formData,
                                                        services: formData.services.filter(
                                                            (item) => item != e.target.value
                                                        ),
                                                    })
                                                }
                                            }}
                                        >
                                            {data}
                                        </Checkbox>
                                    </label>
                                </div>
                            ))}
                        </fieldset>
                        <button
                            type="submit"
                            className="col submit buy-btn"
                            onClick={handleSubmit}
                        >
                            Submit
                        </button>
                    </form>
                </div>
            </div>
        </div>
    )
}

export default ContactForm

server.js(提交方法部分)

const PORT = process.env.PORT || 8000
const express = require("express")
const cors = require("cors")

require("dotenv").config()
const axios = require("axios")

const app = express()
app.use(cors())
app.use(express.json())

const url = process.env.URL
const token = process.env.ASTRA_DB_TOKEN

//create customer
app.post("/customers", async (req, res) => {
    const formData = req.body.formData

    const options = {
        method: "POST",
        headers: {
            Accepts: "application/json",
            "X-Cassandra-Token": token,
            "Content-Type": "application/json",
        },
        data: formData,
    }

    try {
        const response = await axios(url, options)
        res.status(200).json(response.data)
    } catch (e) {
        console.error(e)
        res.status(500).json({ message: e })
    }
})
排查与解决方向
  1. 硬编码API地址问题
    代码中handleSubmit里的请求地址是http://localhost:8000/customers,仅本地环境可访问,部署后外部设备无法连接你本地的服务。必须替换为后端服务的公网部署地址(比如将server.js部署到Heroku、Firebase Functions等平台,获取对应公网域名)。

  2. 异步请求未捕获错误
    当前handleSubmit未用try/catch包裹axios请求,一旦请求失败会直接抛出错误,导致后续逻辑中断且无任何提示。修改示例:

    const handleSubmit = async (e) => {
        e.preventDefault()
        try {
            const response = await axios.post("替换为后端公网地址/customers", { formData })
            if (response.status === 200) {
                console.log("提交成功")
                navigate("/exitpage")
                // 重置表单
                setFormData({
                    datetime: new Date().toISOString(),
                    fName: "",
                    lName: "",
                    email: "",
                    zipCode: "",
                    phoneNumber: "",
                    services: [],
                })
                setPermission(false)
            }
        } catch (error) {
            console.error("提交失败:", error)
            alert("提交失败,请稍后重试")
        }
    }
    
  3. 重复绑定提交事件
    提交按钮同时绑定了onClick={handleSubmit}和表单的onSubmit={handleSubmit},会导致事件触发两次,可能引发异常。去掉按钮的onClick属性,仅保留表单的onSubmit绑定。

  4. 移动设备调试方案

    • 安卓设备:使用Chrome远程调试功能,连接设备后查看控制台与网络请求记录。
    • iOS设备:在iPhone设置中开启「Web检查器」,通过Mac端Safari开发者工具查看设备调试信息。
  5. CORS配置优化
    虽然后端使用了cors()中间件,但如果后端域名与Firebase域名不同,需指定允许的请求来源:

    app.use(cors({ origin: "你的Firebase域名" }))
    
  6. 表单校验问题排查
    移动设备的表单校验逻辑可能与桌面端存在差异,比如type="number"输入框的限制、必填字段未满足时的静默拦截。可在提交前打印表单状态,或添加自定义校验提示,确认是否因校验未通过导致提交失败。


内容的提问来源于stack exchange,提问作者Azula Mongkhonvilay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:57:50