React中如何向后端传递变量、字符串或对象参数?
问题根因
你遇到的参数传递失败、值为空的问题由以下几个逻辑错误共同导致:
- 前后端是完全隔离的运行环境,前端代码里定义的
place变量后端无法直接访问,所有跨端数据必须通过HTTP请求的参数、请求体等合法载体传递,最开始直接在后端代码里引用place变量必然报未定义错误。 useEffect依赖数组为空,只会在组件首次挂载时执行一次,此时finalOption还是初始化的空字符串。后续用户输入更新finalOption时,请求逻辑不会重新触发,发送给后端的永远是空值,和你后端打印出{finalOption : ''}的现象完全吻合。- Axios请求传参格式错误:
axios.get的第二个参数是请求配置对象,不会直接作为请求体发送,你之前直接把place对象传入,没有按规则放到params(GET查询参数)或data(POST请求体)字段中,参数无法被后端正确解析。 - 后端取参、第三方接口调用逻辑错误:你传递的对象字段名是
finalOption,之前写req.body.place自然读不到值;Google Places Text Search接口官方仅支持GET请求,你改成POST调用本身不符合接口规范。
修复步骤
1. 前端代码修正
首先调整请求触发时机:不要在空依赖的useEffect里直接发请求,要么给useEffect加上finalOption依赖并加非空判断,要么绑定到搜索按钮的点击事件上,等用户输入完成后再触发请求。其次按Axios的规范传参。
前端参考代码(GET请求方式):
const [finalOption, setFinalOption] = useState("") const [googlePlaces, setGooglePlaces] = useState([]) // 绑定到搜索按钮点击事件触发 const handleSearch = () => { // 输入为空时不发请求 if(!finalOption.trim()) return axios.get("http://localhost:8000/api/maps", { params: { finalOption } // GET参数放到params配置项里 }) .then(res => { setGooglePlaces(res.data) }) .catch(err => console.log(err)) } // 如果需要输入变化后自动触发搜索,用以下useEffect写法 // useEffect(() => { // if(!finalOption.trim()) return // axios.get("http://localhost:8000/api/maps", { // params: { finalOption } // }) // .then(res => setGooglePlaces(res.data)) // .catch(err => console.log(err)) // }, [finalOption]) // 把finalOption加入依赖数组,值变化时重新执行
如果要改用POST请求,把请求行替换为axios.post("http://localhost:8000/api/maps", { finalOption })即可,第二个参数就是POST请求体。
2. 后端代码修正
首先确认Express服务已经配置了请求体解析中间件,否则无法正常读取req.body内容:
// 放在路由定义之前 app.use(express.json()) app.use(express.urlencoded({extended: true}))
路由处理函数里从对应位置读取参数,调用Google接口时改回GET方法,同时对用户输入做URL编码避免特殊字符导致请求异常。
如果前端用GET传参,后端参考代码:
module.exports.getAll = (req, res) => { // GET传参从req.query读取,字段名和前端传的finalOption对应 const searchKey = req.query.finalOption if(!searchKey) { return res.status(400).json({msg: "搜索关键词不能为空"}) } // 调用Google接口用GET,拼接参数前用encodeURIComponent编码用户输入 axios.get(`https://maps.googleapis.com/maps/api/place/textsearch/json?query=${encodeURIComponent(searchKey)}%20in%20Brooklyn&key=你的Google_API_KEY`) .then(response => { res.json(response.data.results) }) .catch(err => { res.status(400).json(err) console.log(err); }) }
如果前端改用POST传参,只需要把取参行替换为const searchKey = req.body.finalOption,其余逻辑不变。
注意:不要把Google API密钥硬编码在前端代码里,放在后端调用可以避免密钥泄露。
内容的提问来源于stack exchange,提问作者Erick Molina
相关产品推荐
相关产品推荐

