Express 仅不加载页面 return json
Express doesn't load page only return json
问题出现在重新加载页面后,服务器 return 仅 json 而不是页面
我正在使用 React 和来自构建文件夹的 return 静态文件,还有 express handles routing,它仅在 运行 localhost 一切正常
时在生产模式下重现
app.use('/auth', authRoutes);
app.use('/user', userRoutes);
app.use(['/dota2', '/csgo', '/lol'], generalRoutes);
if (process.env.REACT_APP_ENV === 'production') {
console.log('Production is running');
app.use('/', express.static(path.join(__dirname, '../build')));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '../build', 'index.html'));
});
}
有路线
const router = Router();
router.get('/live', liveMatches);
router.get('/upcoming', upcomingMatches);
router.get('/past', pastMatches);
router.get('/:matchId', getMatchById);
router.get('/opponents/:tournamentId', opponents);
router.post('/past-team-matches', pastTeamMatches);
您可以访问 mySite,您将看到 json 作为结果,但是如果您在 URL 中清除 matchId 并单击任何匹配项页面将正常加载
还有react-router
<ServiceRoute
key={key}
path={['/dota2', '/csgo', '/lol']}
exact
access
component={Matches}
/>
<ServiceRoute
key={key}
path={['/dota2/:matchId', '/csgo/:matchId', '/lol/:matchId']}
exact
access
component={MatchInfo}
/>
让我们按照 express 在这种情况下所做的路由匹配:
- 在寻找
/dota2/566624
时,会匹配到这里:app.use(['/dota2', '/csgo', '/lol'], generalRoutes);
和return the JSON.
- 当寻找
/dota2
时,它不会匹配app.use(['/dota2', '/csgo', '/lol'], generalRoutes);
所以它会继续向下直到匹配app.get('*', (req, res) => {
,服务于React页面。
我在这里看到的问题是,您为 API 和 React 上的前端路由使用了完全相同的路由。理想情况下,当从同一台服务器为 API 和前端应用程序提供服务时,您应该为 API 路由添加前缀,这样它们就不会与前端路由发生冲突。假设您在 API 路由前加上:/api
。现在你有:
app.use('/api/auth', authRoutes);
app.use('/api/user', userRoutes);
app.use(['/api/dota2', '/api/csgo', '/api/lol'], generalRoutes);
// ... everything is the same down here
/api/dota2/566624
。将与 return 在第一次加载时 JSON 的端点匹配。
/dota2/566624
。将不匹配 JSON 端点,并将跟随加载 React 应用程序的 '*'
路由,稍后,一旦加载应用程序,该路由将由您在 React 上使用的路由器处理申请。
不要像我在上面的示例中那样添加前缀,也使用您一直用于此目的的 const router = Router();
。我对前缀进行了硬编码,以便可以使示例简短。
最后一个问题是:为什么这在开发中没有发生?
我没有所有的信息,但据我所知,你从不同的服务器为前端应用程序提供服务,而不是 运行 API;在那种情况下,你不会有路由冲突,因为它们是来自不同端口的服务器,例如前端服务于 localhost:8080
和 API 服务于 localhost:5000
.
希望对您有所帮助!如果您需要信息,请发表评论!
问题出现在重新加载页面后,服务器 return 仅 json 而不是页面
我正在使用 React 和来自构建文件夹的 return 静态文件,还有 express handles routing,它仅在 运行 localhost 一切正常
时在生产模式下重现app.use('/auth', authRoutes);
app.use('/user', userRoutes);
app.use(['/dota2', '/csgo', '/lol'], generalRoutes);
if (process.env.REACT_APP_ENV === 'production') {
console.log('Production is running');
app.use('/', express.static(path.join(__dirname, '../build')));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '../build', 'index.html'));
});
}
有路线
const router = Router();
router.get('/live', liveMatches);
router.get('/upcoming', upcomingMatches);
router.get('/past', pastMatches);
router.get('/:matchId', getMatchById);
router.get('/opponents/:tournamentId', opponents);
router.post('/past-team-matches', pastTeamMatches);
您可以访问 mySite,您将看到 json 作为结果,但是如果您在 URL 中清除 matchId 并单击任何匹配项页面将正常加载
还有react-router
<ServiceRoute
key={key}
path={['/dota2', '/csgo', '/lol']}
exact
access
component={Matches}
/>
<ServiceRoute
key={key}
path={['/dota2/:matchId', '/csgo/:matchId', '/lol/:matchId']}
exact
access
component={MatchInfo}
/>
让我们按照 express 在这种情况下所做的路由匹配:
- 在寻找
/dota2/566624
时,会匹配到这里:app.use(['/dota2', '/csgo', '/lol'], generalRoutes);
和return the JSON. - 当寻找
/dota2
时,它不会匹配app.use(['/dota2', '/csgo', '/lol'], generalRoutes);
所以它会继续向下直到匹配app.get('*', (req, res) => {
,服务于React页面。
我在这里看到的问题是,您为 API 和 React 上的前端路由使用了完全相同的路由。理想情况下,当从同一台服务器为 API 和前端应用程序提供服务时,您应该为 API 路由添加前缀,这样它们就不会与前端路由发生冲突。假设您在 API 路由前加上:/api
。现在你有:
app.use('/api/auth', authRoutes);
app.use('/api/user', userRoutes);
app.use(['/api/dota2', '/api/csgo', '/api/lol'], generalRoutes);
// ... everything is the same down here
/api/dota2/566624
。将与 return 在第一次加载时 JSON 的端点匹配。/dota2/566624
。将不匹配 JSON 端点,并将跟随加载 React 应用程序的'*'
路由,稍后,一旦加载应用程序,该路由将由您在 React 上使用的路由器处理申请。
不要像我在上面的示例中那样添加前缀,也使用您一直用于此目的的 const router = Router();
。我对前缀进行了硬编码,以便可以使示例简短。
最后一个问题是:为什么这在开发中没有发生?
我没有所有的信息,但据我所知,你从不同的服务器为前端应用程序提供服务,而不是 运行 API;在那种情况下,你不会有路由冲突,因为它们是来自不同端口的服务器,例如前端服务于 localhost:8080
和 API 服务于 localhost:5000
.
希望对您有所帮助!如果您需要信息,请发表评论!