Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
746 views
in Technique[技术] by (71.8m points)

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

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 on url paths. So the following is my index.js which handles the routing:

 const history = useRouterHistory(createHistory)({
     basename: '/test'
})
class Tj extends React.Component {

render() {

    return (
        <Router history={history}>
            <Route path={"/"} component={Bridge} >
                <IndexRoute component={Home} />
                <Route path={"user"} component={T} />
                <Route path={"home"} component={Home} />
            </Route>
            <Route path={"/t/"} component={Bridge2} >
                <IndexRoute component={T} />
                <Route path={"contact"} component={Home} />
            </Route>
        </Router>
    );
}
}
render(
<Provider store={store}>
    <Tj/>
</Provider>,
window.document.getElementById('mainContainer'));

As you can see I am using test as a root directory and based on user's input for url I decide which header should I use. Also here is Bridge2.js:

export class Bridge2 extends React.Component {
render() {

    return (
        <div>
            <div className="row">
                <Header2/>
            </div>
            <div className="row">
                {this.props.children}
            </div>
        </div>
    );
}
}

and Bridge.js:

export class Bridge extends React.Component {
render() {
  //  alert(this.props.children.type);
    var Content;

    if(this.props.children.type){
    Content=<div>
        <div className="row">
            <Header/>
        </div>
        <div className="row">
            {this.props.children}
        </div>
    </div>;
    }
    else{
        Content=<div>
            <div className="row">
                <Header/>
            </div>
            <div className="row">
                {this.props.children}
            </div>
        </div>;
    }
    return (
        Content
    );
}
}

When I run this in webpack dev server every thing works fine. For instance when I use http://localhost:3003/test/ bridge.js is loaded and if I run http://localhost:3003/test/t/ bridge2.js is loaded which is expected.

However since web pack dev server is not a production server I use tomcat and for now I use the eclipse web application project and I copied my bundle.js file and index.html over there. Now the problem is when I run the tomcat server it is able to recognize and show this path fine:

http://localhost:8080/test/ but when for http://localhost:8080/test/t/ I get:

HTTP Status 404 - /test/t/

which basically says the resource file is not available. As far as what I observe this is not a problem in coding since routing works fine in web pack dev server but when it comes to tomcat it seems that react routing is not able to handle it. Is there anything wrong with what I am doing? Is doable this way at all? Can anyone help?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...