如何排查Axios POST请求未向Heroku后端发送payload数据的问题
问题说明
- 目标:React前端应用可通过POST请求向Heroku后端发送数据
- 技术栈:React,使用Axios发起请求
问题表现
尝试在Axios post请求函数处设置断点未生效,添加带.then的Promise语句后控制台也无任何响应返回。已通过POSTMAN测试该POST请求,数据可正常发送,返回状态码200。
同时尝试了Promise和try-catch两种写法,Promise版本因语法问题被注释。目前前端try-catch未捕获到任何报错,后端也未触发预期的控制台日志输出,但Postman发送请求时后端可正常打印日志。
原代码
前端React组件代码
import React from 'react'; import {useState} from 'react'; import Axios from 'axios' //import { response } from 'express'; const QuoteForm = () => { const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [question, setQuestion] = useState(""); /* This is the promise version however it has sytax issues : the funtion containing the promise doesn't properly close so return expects } instead has ) const custData = { name:name , email:email , question:question} ; const submitQuestion = new Promise ((resolve, reject)=> resolve(Axios.post('https://hookahsite-backend.herokuapp.com || https://localhost:8000 ' , custData) .then(()=> {console.log("success, data sent")}) .catch(()=>{console.log("error when sending")}) ) */ //this uses try catch however the backend is not getting hit with any data //tested this same request in Postman and it works function submitQuestion() { try { Axios.post('https://hookahsite-backend.herokuapp.com ' , { name:name , email:email , question:question }, ) } catch (err) {console.error(err);} } return( <React.Fragment> <form id="quoteForm" > <h1 id="quoteTitle">Quote Help Form</h1> <p id="quotePar">Please provide your Name, Contact Email, and what products you would like more information about in this form :</p> <label id="formName" className="Form"> Name: <input type="text" name="name" onChange={(event) => { setName(event.target.value);}} /> </label> <label id="formEmail" className="Form"> Email: <input type="text" name="email" onChange={(event) => { setEmail(event.target.value); }}/> </label> <br/> <label id="formQuestion" className="Form" > What products would you like to know more about: <input type="text" name="help" onChange={(event) => { setQuestion(event.target.value); }}/> </label> <br/> <br/> <button id="quoteSubmit" type="submit" onClick = { submitQuestion } /* old way {()=> submitQuestion() } */ >Submit </button> </form> </React.Fragment> ) }; export default QuoteForm;
后端服务代码
app.post('/' , (req,res) => { const {email, name, question} = req.body; res.header("Access-Control-Allow-Origin", "*"); console.log(`Your Email is ${email} and your name is ${name} and your ${question}`); //MYSQL updating table pool.query("INSERT INTO customer_questions (name, email, question) VALUES (?,?,?)", [name, email, question], (err,res)=> { if (err) { console.log(err) }else { res.send('data sent') } } ); });
问题原因&修复方案
核心问题
- 表单默认提交行为未阻止:使用了
type="submit"的按钮,点击后表单会触发默认的页面刷新行为,异步请求还没完成页面就重载了,所以断点不生效、控制台无日志、后端收不到请求。 - 异步请求未做异常捕获:Axios.post是异步方法,普通的try-catch无法捕获异步抛出的异常,所以就算请求出错catch逻辑也不会执行。
- 代码语法问题:
- 注释的Promise版本括号未正确闭合,且URL字符串内直接写
||做判断是无效写法,不能在字符串内执行逻辑运算符。 - Axios请求的目标URL末尾多余空格,可能导致请求路径异常。
- 后端代码中数据库查询的回调参数
res和外层路由的响应对象res重名,会导致响应发送失败。
- 注释的Promise版本括号未正确闭合,且URL字符串内直接写
修正后的代码
前端修正版
import React from 'react'; import {useState} from 'react'; import Axios from 'axios' const QuoteForm = () => { const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [question, setQuestion] = useState(""); // 异步提交方法,阻止默认表单行为 async function submitQuestion(e) { // 阻止表单默认刷新 e.preventDefault(); try { // 可根据环境切换请求地址,不要写在字符串内 const baseUrl = process.env.NODE_ENV === 'development' ? 'http://localhost:8000' : 'https://hookahsite-backend.herokuapp.com'; await Axios.post(baseUrl, { name, email, question }); console.log("success, data sent"); } catch (err) { console.error("error when sending:", err); } } return( <React.Fragment> {/* 绑定onSubmit事件,比按钮绑定onClick更规范 */} <form id="quoteForm" onSubmit={submitQuestion}> <h1 id="quoteTitle">报价咨询表单</h1> <p id="quotePar">请填写您的姓名、联系邮箱,以及您想要了解更多信息的产品:</p> <label id="formName" className="Form"> 姓名: <input type="text" name="name" onChange={(e) => setName(e.target.value)} /> </label> <label id="formEmail" className="Form"> 邮箱: <input type="email" name="email" onChange={(e) => setEmail(e.target.value)} /> </label> <br/> <label id="formQuestion" className="Form" > 您想了解哪些产品的相关信息: <input type="text" name="help" onChange={(e) => setQuestion(e.target.value)} /> </label> <br/> <br/> <button id="quoteSubmit" type="submit">提交</button> </form> </React.Fragment> ) }; export default QuoteForm;
后端修正版
// 全局设置CORS头,避免每个路由重复配置 app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Content-Type"); next(); }); app.post('/' , (req,res) => { const {email, name, question} = req.body; console.log(`Your Email is ${email} and your name is ${name} and your ${question}`); // 修改回调参数名,避免和外层res冲突 pool.query("INSERT INTO customer_questions (name, email, question) VALUES (?,?,?)", [name, email, question], (err, result)=> { if (err) { console.log(err) return res.status(500).send('database error'); } res.send('data sent'); } ); });
内容的提问来源于stack exchange,提问作者ben holsinger
相关产品推荐
相关产品推荐

