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 }) } })
硬编码API地址问题
代码中handleSubmit里的请求地址是http://localhost:8000/customers,仅本地环境可访问,部署后外部设备无法连接你本地的服务。必须替换为后端服务的公网部署地址(比如将server.js部署到Heroku、Firebase Functions等平台,获取对应公网域名)。异步请求未捕获错误
当前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("提交失败,请稍后重试") } }重复绑定提交事件
提交按钮同时绑定了onClick={handleSubmit}和表单的onSubmit={handleSubmit},会导致事件触发两次,可能引发异常。去掉按钮的onClick属性,仅保留表单的onSubmit绑定。移动设备调试方案
- 安卓设备:使用Chrome远程调试功能,连接设备后查看控制台与网络请求记录。
- iOS设备:在iPhone设置中开启「Web检查器」,通过Mac端Safari开发者工具查看设备调试信息。
CORS配置优化
虽然后端使用了cors()中间件,但如果后端域名与Firebase域名不同,需指定允许的请求来源:app.use(cors({ origin: "你的Firebase域名" }))表单校验问题排查
移动设备的表单校验逻辑可能与桌面端存在差异,比如type="number"输入框的限制、必填字段未满足时的静默拦截。可在提交前打印表单状态,或添加自定义校验提示,确认是否因校验未通过导致提交失败。
内容的提问来源于stack exchange,提问作者Azula Mongkhonvilay

