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 在这种情况下所做的路由匹配:

  1. 在寻找/dota2/566624时,会匹配到这里:app.use(['/dota2', '/csgo', '/lol'], generalRoutes);和return the JSON.
  2. 当寻找/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
  1. /api/dota2/566624。将与 return 在第一次加载时 JSON 的端点匹配。
  2. /dota2/566624。将不匹配 JSON 端点,并将跟随加载 React 应用程序的 '*' 路由,稍后,一旦加载应用程序,该路由将由您在 React 上使用的路由器处理申请。

不要像我在上面的示例中那样添加前缀,也使用您一直用于此目的的 const router = Router();。我对前缀进行了硬编码,以便可以使示例简短。

最后一个问题是:为什么这在开发中没有发生? 我没有所有的信息,但据我所知,你从不同的服务器为前端应用程序提供服务,而不是 运行 API;在那种情况下,你不会有路由冲突,因为它们是来自不同端口的服务器,例如前端服务于 localhost:8080 和 API 服务于 localhost:5000.

希望对您有所帮助!如果您需要信息,请发表评论!