react routing is able to handle different url path but tomcat returns 404 not available resources

后端 未结 8 1551
时光取名叫无心
时光取名叫无心 2020-12-07 15:01

I am new in reactjs and I have a little project in reactjs to play with and learn it. I need to have to type of headers which will be shown based o

相关标签:
8条回答
  • 2020-12-07 15:21

    While I am not familiar with Tomcat, what is most likely happening is that your server is looking for a /test/t or /test/t/index.html file, and since none exists, it is returning a 404 error.

    When you use a browser history, you need to have a server that can handle routing. Typically this will be a wildcard (*) route that returns your index.html file (which in turn will return your bundled js as well as any other static files included in the index file).

    One solution is to switch to using a hash router. If you are not able to do routing on the server (particularly relevant for people hosting static content), then hash routing is necessary. However, because you are using a server, you should be able to setup routing that will allow you to use a browser router.

    As I said before, I am not familiar with Tomcat, so I will just describe what the configuration should be.

    1. All requests for static files should be served regularly.
    2. All other requests to /test/* (where * is any URL) should serve your index.html file.
    0 讨论(0)
  • 2020-12-07 15:25

    I think an answer to the OP's question should address also the access to static resources via the default servlet.

    In my understanding the problem appears in multi-view React applications where a Router is used to alter the page URL in order to reflect the state of the application. This is nice, but if you reload the page by accident you get 404 since there won't be any resource matching the altered URL. It also means such altered URLs can't be bookmarked as direct access to different application views. Unless, we get a little help from the server side.

    There are more solutions possible, depending on how the access to static resources is handled, or the chosen implementation (filter, servlet or even JSP), but the basic idea is to serve the main application HTML file for every Routes defined in React.

    Supposing you have you have two React Routes defined in your application:

    <Route path={"view1"} component={View1} />
    <Route path={"view2"} component={View2} />
    

    You could create a RouterServlet to forward requests to /view1 or /view2 back to the context root (/), supposing you mapped the application here.

    void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException 
    {
        request.getServletContext().getRequestDispatcher("/").forward(request, response);
    }
    

    You can configure it like this:

    <servlet>
        <servlet-name>RouterServlet</servlet-name>
        <servlet-class>package.RouterServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RouterServlet</servlet-name>
        <url-pattern>/view1/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>RouterServlet</servlet-name>
        <url-pattern>/view2/*</url-pattern>
    </servlet-mapping>
    
    0 讨论(0)
  • 2020-12-07 15:36

    For Tomcat versions below 8. You can just add a web.xml file and route the 404 to index.html.

    webapps/[my-app-name]/WEB-INF/web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
              http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
              version="2.4">
    
      <display-name>my-app-name</display-name>
    
      <error-page>
        <error-code>404</error-code>
        <location>/index.html</location>
      </error-page>
    
    </web-app>
    
    0 讨论(0)
  • 2020-12-07 15:37

    In my case I wanted a simple solution as with creating a customer error page. However that solution still sets a status code 404 which is not desired.

    So I use a small jsp file which will set status code to 200 before outputting the SPA's index.html.

    I hope this helps someone else looking for a simple solution without returning status 404.

    web.xml

    <error-page>
        <error-code>404</error-code>
        <location>/spa.jsp</location>
    </error-page>
    

    spa.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%
        response.setStatus(200);
    %><%@include file="./dashboard/index.html"%>
    
    0 讨论(0)
  • 2020-12-07 15:43

    I have the same problem routing not working. If 404 not redirecting and loading the index.html problem. I tried several ways and finally found a solution which fixed my problem.

    This worked for me on Tomcat 8

    inside ROOT folder of Tomcat make a new folder WEB-INF and create web.xml 
    

    You can do this by

    sudo gedit /opt/tomcat/webapps/ROOT/WEB-INF/web.xml
    

    paste the below in the web.xml

    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
        <display-name>your_display_name</display-name>
    
        <error-page>
            <error-code>404</error-code>
            <location>/index.html</location>
        </error-page>
    
    </web-app>
    

    Restart the Tomcat. This fixed the routing problem for me. Hope this helps for someone I think. Thanks

    0 讨论(0)
  • 2020-12-07 15:46

    First, you must be aware of the following differences when using react-router.

    When you enter localhost:3003/test/ in your browser, it will request the server, and then it will receive /test/index.html, the js bundle, css, ...

    After that, whenever you click an internal link (eg. localhost:3003/test/t/), your browser will not request the server again. React-router will resolve this client-side, re-render portions of the page, and update browser's address bar (using HTML5 pushstate()), without triggering another server request.

    When you enter localhost:3003/test/t/ directly in the address bar, your browser will request the server, and Tomcat does not have /test/t/index.html or so, and it returns a 404. It's because Tomcat doesn't know anything about react-redux nor javascript.

    A way to handle this is to configure 404 errors to be forward to /test/index.html. It's probably how your webpack dev server is configured by default.

    There is plenty of examples of doing this on apache, if you have one in front of our Tomcat. Search for html5 pushstate apache config.

    Here is an example:

    httpd.conf:

    ...
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.html [L]
     </IfModule>
    ...
    

    If you are using Tomcat alone, you may try to specify this in the web.xml, inside your .war file:

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

    Note that this is not a react-router specific problem, every app that uses HTML5 pushstate() needs to handle this somehow. Javascript servers may handle this more seamlessly though.

    0 讨论(0)
提交回复
热议问题