React代理无法连接首页路由,其他路由正常的问题排查
React路由跳转Home链接时fetch请求报错问题
我在package.json中配置了代理http://localhost:5000,前端使用React Router实现路由跳转。点击Home链接时无fetch请求发送,浏览器控制台报错Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0,但Business链接可正常工作。以下是完整的前后端代码:
前端代码
import React from 'react'; import {BrowserRouter,Routes,Route} from 'react-router-dom'; import Nav from './components/nav'; import Home from './components/home'; import Business from './components/business'; const [articles, setArticles] = React.useState(''); const [url, setUrl] = React.useState("/"); React.useEffect(() => { fetch(url) .then(res => res.json()) .then(data => {setArticles(data)}) }, [url]); console.log(url); function changeTopic(e, sub) { setUrl(`/${sub}`); } return ( <BrowserRouter> <Nav change = {changeTopic}/> <Routes> <Route path='/' element={<Home articles={articles} />} /> <Route path='/topics/:id' element={<Business articles={articles} />} /> </Routes> </BrowserRouter> ) export default App;
Nav.js代码
import {Link} from 'react-router-dom'; export default function Nav(props){ return ( <div> <ul> <li> <Link to = "/" onClick = {(e) => props.change(e,'')}>Home</Link> </li> <li> <Link to = "/topics/business" onClick = {(e) => props.change(e,'topics/business')}>Business</Link> </li> </ul> </div> ) }
home.js代码
export default function Home(props){ return ( <div> <p>{props.articles.data}</p> </div> ) }
后端代码
const express = require('express'); const cors = require('cors'); const path = require('path'); const app = express(); const PORT = process.env.PORT || 5000; app.use(cors()); app.use('/', function(req,res){ console.log(req.url) res.json({"data" : "inside home"}) }); app.use('/topics/business',function(req,res){ console.log(req.url) res.json({"data" : "inside topics"}) }); app.listen(PORT,() => { console.log(`running on port ${PORT}`) });
问题原因分析
- URL拼接错误:点击Home时,
changeTopic函数传入的sub是空字符串,拼接后url变成//。fetch请求这个路径时,会指向前端的静态资源(比如index.html),而非后端接口,返回的HTML内容解析成JSON就会触发语法错误。 - React钩子位置错误:原代码中
useState和useEffect写在函数中间,不符合React钩子必须在函数顶层的规则,可能导致逻辑异常。 - 后端路由匹配问题:使用
app.use作为根路径路由,会匹配所有以/开头的请求,容易和其他路由冲突,且无法精准响应GET请求。 - 空值访问风险:Home组件直接访问
props.articles.data,当articles初始为空字符串时会触发报错。
解决方案
1. 修正URL拼接逻辑
修改changeTopic函数,避免生成无效路径:
function changeTopic(e, sub) { setUrl(sub ? `/${sub}` : "/"); }
2. 调整React钩子位置
将所有钩子移到函数最顶层,符合React规则:
function App() { const [articles, setArticles] = React.useState(null); const [url, setUrl] = React.useState("/"); React.useEffect(() => { fetch(url) .then(res => { if (!res.ok) throw new Error('请求失败'); return res.json(); }) .then(data => setArticles(data)) .catch(err => console.error('请求错误:', err)); }, [url]); function changeTopic(e, sub) { setUrl(sub ? `/${sub}` : "/"); } return ( <BrowserRouter> <Nav change={changeTopic}/> <Routes> <Route path='/' element={<Home articles={articles} />} /> <Route path='/topics/:id' element={<Business articles={articles} />} /> </Routes> </BrowserRouter> ) } export default App;
3. 后端改用精准路由
将app.use替换为app.get,确保仅响应GET请求:
app.get('/', function(req,res){ console.log(req.url) res.json({"data" : "inside home"}) }); app.get('/topics/business',function(req,res){ console.log(req.url) res.json({"data" : "inside topics"}) });
4. 组件添加空值判断
修改Home组件,避免空值访问报错:
export default function Home(props){ return ( <div> <p>{props.articles?.data || '加载中...'}</p> </div> ) }
内容的提问来源于stack exchange,提问作者user17666483
相关产品推荐
相关产品推荐

