React+Express部署测试:非根路由返回404错误求助
问题:React + Express 部署后仅根路由可访问,其他路由返回404
我搭建了React与Express项目用于部署测试,但只有Express的根路由("/")能正常响应,其他所有路由都返回404错误。比如在React的Detail页面中,点击向/hello路由发送请求的按钮时,就会返回404错误。
React Home.tsx
export default function Home() { const [loading, setLoading] = useState(true); const [movies, setMovies] = useState<Movie[] | null>(null); useEffect(() => { getMovies(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const getMovies = async () => { const response: GetMoviesResponse = await axios.get( 'https://flyio-server3001.fly.dev' ); setMovies(response.data.movies); setLoading(false); }; return ( <div> <h1>안녕하세요~ 최근 영화를 소개합니다!</h1> <h5>이미지를 클릭 시 영화 상세 정보를 확인할 수 있습니다.</h5> <MovieList> {loading && <li>영화 리스트 로딩 중...</li>} {movies && movies.map((movie) => ( <li key={movie.id}> <Link to={ process.env.NODE_ENV === 'development' ? `/movies/${movie.id}` : process.env.PUBLIC_URL + `/movies/${movie.id}` } state={{ movie }} > <img src={movie.medium_cover_image} alt={movie.title} /> </Link> <Title>{movie.title}</Title> </li> ))} </MovieList> </div> ); }
React Detail.tsx
export default function Detail() { const [loading, setLoading] = useState(true); const [movie, setMovie] = useState<Movie | null>(null); const { state } = useLocation(); useEffect(() => { const movie: Movie = state.movie; setMovie(movie); setLoading(false); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const hello = async (e: React.MouseEvent<HTMLButtonElement>) => { e.preventDefault(); const response = await axios.get('https://flyio-server3001.fly.dev/hello'); console.log(response); }; return ( <div> <Link to={ process.env.NODE_ENV === 'development' ? `/` : process.env.PUBLIC_URL + `/` } >{`<= 홈으로`}</Link> <button onClick={hello}>메시지 받기</button> {loading && <div>영화 상세 정보 로딩 중.....</div>} {movie && ( <div> <img src={movie.medium_cover_image} alt={movie.title} /> <h1>{movie.title}</h1> <h5>{movie.year}년 개봉</h5> <h5>상영 시간 : {movie.runtime}분</h5> <h5>줄거리 : </h5> <p>{movie.summary}</p> </div> )} </div> ); }
Node.js app.ts
import express from 'express'; import fetch from 'node-fetch'; import cors from 'cors'; const app = express(); const PORT = process.env.PORT || 3001; app.use(cors()); app.use('/', require('./index')); app.listen(PORT, () => `✅ ${PORT} port server connected success`);
Node.js index.ts
import express from 'express'; const indexRouter = express.Router(); indexRouter.get('/', async (req, res) => { const response = await ( await fetch('https://yts.mx/api/v2/list_movies.json') ).json(); return res.status(304).json({ movies: response.data.movies }); }); indexRouter.get('/hello', (req, res) => { return res.json({ message: 'Hello Fly.io Server !!!' }); }); module.exports = indexRouter;
解决方案
问题出在Express的路由导入导出语法不兼容:你在index.ts中用ES模块语法编写,但app.ts里用CommonJS的require导入,导致除根路由外的其他路由未被正确注册。
修复步骤:
- 修改
index.ts的导出方式为ES模块:
// index.ts import express from 'express'; const indexRouter = express.Router(); indexRouter.get('/', async (req, res) => { const response = await ( await fetch('https://yts.mx/api/v2/list_movies.json') ).json(); return res.status(304).json({ movies: response.data.movies }); }); indexRouter.get('/hello', (req, res) => { return res.json({ message: 'Hello Fly.io Server !!!' }); }); export default indexRouter; // 替换原module.exports
- 修改
app.ts的导入方式为ES模块:
// app.ts import express from 'express'; import fetch from 'node-fetch'; import cors from 'cors'; import indexRouter from './index'; // 替换原require导入 const app = express(); const PORT = process.env.PORT || 3001; app.use(cors()); app.use('/', indexRouter); app.listen(PORT, () => console.log(`✅ ${PORT} port server connected success`));
- 在项目的
package.json中添加"type": "module",明确告诉Node.js使用ES模块:
{ "type": "module" }
修改完成后,Express就能正确注册所有路由,/hello等路由即可正常响应。
内容的提问来源于stack exchange,提问作者pickle23
相关产品推荐
相关产品推荐

