react routing能够处理不同的url路径,但tomcat返回404不可用的资源

Ham*_*aee 22 reactjs react-router

我是新手,reactjs我有一个小项目reactjs可以玩并学习它.我需要输入基于url路径显示的标题类型.所以以下是我的index.js处理路由:

 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'));
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我使用test作为根目录,并根据用户的url输入决定我应该使用哪个头.这里还有Bridge2.js:

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

    return (
        <div>
            <div className="row">
                <Header2/>
            </div>
            <div className="row">
                {this.props.children}
            </div>
        </div>
    );
}
}
Run Code Online (Sandbox Code Playgroud)

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
    );
}
}
Run Code Online (Sandbox Code Playgroud)

当我在webpack开发服务器中运行它时,每件事情都可以.例如,当我使用http://localhost:3003/test/bridge.js加载时,如果我运行http://localhost:3003/test/t/bridge2.js加载,这是预期的.

但是,由于web pack dev服务器不是生产服务器,我使用tomcat,现在我使用eclipse web应用程序项目,然后我复制了我的bundle.js文件和index.html.现在的问题是,当我运行tomcat服务器时,它能够识别并显示此路径:

http://localhost:8080/test/但是当http://localhost:8080/test/t/我得到:

HTTP状态404 - /test/t /

这基本上说资源文件不可用.就我所观察到的而言,这不是编码中的问题,因为路由在web pack dev服务器中运行良好,但是当涉及到tomcat时,似乎反应路由无法处理它.我在做什么有什么不对吗?这样可行吗?有人可以帮忙吗?

小智 38

首先,使用react-router时必须注意以下差异.

当您在浏览器中输入"localhost:3003/test /"时,它将请求服务器,然后它将收到/test/index.html,js包,css,...

之后,每当您单击内部链接(例如'localhost:3003/test/t /')时,您的浏览器将不再请求服务器.

React-router将解析此客户端,重新呈现页面的部分,并更新浏览器的地址栏(使用html5 pushstate),而不会触发另一个服务器请求.

当您在地址栏中直接输入"localhost:3003/test/t /"时,您的浏览器将请求服务器,而Tomcat没有/test/t/index.html左右,它返回404.这是因为Tomcat对react-redux和javascript一无所知.

处理此问题的一种方法是将404错误配置为转发到/test/index.html.这可能是默认配置webpack dev服务器的方式.

如果你在Tomcat面前有一个这样的例子,那么在apache上有很多这样的例子.搜索"html5 pushstate apache config".

这是一个例子

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>
...
Run Code Online (Sandbox Code Playgroud)

如果您单独使用tomcat,则可以尝试在war.xml文件中的web.xml中指定它.

...
<error-page>
    <error-code>404</error-code>
    <location>/index.html</location>
</error-page>
...
Run Code Online (Sandbox Code Playgroud)

请注意,这不是特定于反应路由的问题,每个使用html5 pushstate的应用都需要以某种方式处理此问题.Javascript服务器可以更无缝地处理这个问题.


Shi*_*eph 9

我有同样的问题路由不工作。如果 404 没有重定向和加载 index.html 问题。我尝试了几种方法,终于找到了解决我问题的解决方案。

这在 Tomcat 8 上对我有用

inside ROOT folder of Tomcat make a new folder WEB-INF and create web.xml 
Run Code Online (Sandbox Code Playgroud)

你可以这样做

sudo gedit /opt/tomcat/webapps/ROOT/WEB-INF/web.xml
Run Code Online (Sandbox Code Playgroud)

将以下内容粘贴到 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>
Run Code Online (Sandbox Code Playgroud)

重启Tomcat。这为我解决了路由问题。希望这对我认为的人有所帮助。谢谢


Aci*_*ier 9

Tomcat 8及更高版本为此提供了一个简单的内置解决方案。您无需将其放在Apache后面即可处理此问题,也不必切换到哈希路由,也无需修改重定向页面即可回到自己服务器上的其他位置...

使用Tomcat重写

它适用于任何具有UI路由的单页面应用程序框架,例如React,Angular,ExtJS等。


简而言之:

1)将RewriteValve添加到 /tomcat/webapps/{your-web-app-directory}/META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>  
  <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
  ... your other context items
</Context>
Run Code Online (Sandbox Code Playgroud)

2)创建一个名为:的文件/tomcat/webapps/{your-web-app-directory}/WEB-INF/rewrite.config,然后为要指向索引页面的任何路径添加重写规则:

RewriteRule ^/user(.*)$    /index.html [L]
RewriteRule ^/home(.*)$    /index.html [L]
RewriteRule ^/contact(.*)$ /index.html [L]
Run Code Online (Sandbox Code Playgroud)

这些规则告诉Tomcat将所有带有这三个命名路径的所有请求直接发送到index.html。

3)重新启动Tomcat

这些规则可能会变得更复杂,例如将所有请求(除了特定路径)发送到index.html ,这对于/api必须在之外的地方调用很有用index.html。上面的链接涵盖了有关如何使用Tomcat Rewrite的其他示例。


Bip*_*pul 6

我的解决方案就像是JSP引擎的解决方法(例如Tomcat),但它可以用最少的代码工作.

我使用以下代码创建了一个与"index.html"(在内容根文件夹中)并行的"index.jsp":

的index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@include file="index.html"%>
Run Code Online (Sandbox Code Playgroud)

我将所有URL配置为在web.xml中重定向到此JSP

web.xml中

<servlet>
    <servlet-name>index</servlet-name>
    <jsp-file>index.jsp</jsp-file>
</servlet>
<servlet-mapping>
    <servlet-name>index</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)

现在,任何请求Tomcat的URL都将在内部被重定向到index.html的index.jsp.一旦react-router在浏览器中加载,它就会负责呈现正确的组件和后续请求.