React前端工程部署(Tomcat)后404的解决方法 (使用ReactRouter v6)

1,409 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」。

前后端分离的项目,前端是 React 工程,使用 create-react-app 创建,路由使用的是 ReactRouter v6,部署时遇到了几个小问题。
网上搜索了一下,发现也是经常碰到的问题。
记录一下解决方法,有同样情况的 XDM 可以参考。

ReactRouter v6 刚发布了不长时间。
同样的解决方法对于 v5 不一定有效,建议先升级到 v6,貌似有很多不兼容的改动。

ReactRouter v6 官方文档:
Declarative routing for React apps at any scale | React Router
该网站有详细的迁移方法。


本文相关代码:helloreact/reactrouter6 at main · bettersun/helloreact · GitHub

具体的问题:

  1. 部署时找不到资源(静态资源404)

    错误如图:

    asset404.png

    修改 package.json,设置 homepage 。

    package.json

      "name": "reactrouter6",
      "version": "0.1.0",
      "private": true,
      "homepage": "reactrouter6",
      "dependencies": {
          ...
      }
    

    修改后重新部署,站点正常显示:

    reactrouter6.png

  2. 跳转时站点根路径丢失

    错误如图:

    reactrouter6_2.gif

    能看到点击链接后,部署的站点的 URL 消失了。

    这种情况需要设置一下 BrowserRouter 的 basename 。 ReactRouter v6是可以的,之前的版本好像不可以,没再试。 如果不可以的话,可以升级到 v6 之后再用此办法。

    <BrowserRouter basename="reactrouter6">
      <App />
    </BrowserRouter>
    

    修改后重新部署,点击链接,站点路径不再消失。

    reactrouter6_22.gif

  3. 跳转后刷新404

    错误如图:

    iShot2021-11-15 15.30.10.png

    需要在站点下创建 WEB-INF 目录,然后在目录下 创建 web.xml 文件,文件里添加以下内容。

    webapps/{站点目录}/WEB-INF/web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
      version="4.0">
    
        <error-page>
          <error-code>404</error-code>
          <location>/index.html</location>
        </error-page>
    </web-app>
    

    修改后正常刷新:

    reactrouter6_3.gif

    因为是单页应用,所有的内容都是在 index.html 里渲染,所以这里报错后又重定向到 index.html 后就能正常渲染了。

    这里有个点,一般 React 项目编译出来的页面都是在 index.html 中渲染。如果因为某些原因,index.html 改成了别的名字,这个地方的404的重定向就要改成对应的文件名。

    例如:

    <error-page>
      <error-code>404</error-code>
      <location>/welcome.html</location>
    </error-page>