我在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'));
字符串
正如你所看到的,我使用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>
);
}
}
型
和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
);
}
}
型
当我在webpack dev server中运行它时,一切都很好。例如,当我使用http://localhost:3003/test/
时,bridge.js被加载,如果我运行http://localhost:3003/test/t/
,bridge2.js被加载,这是预期的。
然而,由于web包开发服务器不是生产服务器,我使用tomcat,现在我使用eclipse web应用程序项目,我复制了我的bundle.js文件和index.html。现在的问题是,当我运行tomcat服务器时,它能够很好地识别并显示这个路径:http://localhost:8080/test/
,但当http://localhost:8080/test/t/
时,我得到:
HTTP Status 404 - /test/t/
基本上说资源文件不可用。据我观察,这在编码中不是问题,因为路由在web包开发服务器中工作得很好,但是当涉及到tomcat时,react路由似乎无法处理它。我做的事有什么不对吗?是否可行?
9条答案
按热度按时间xwmevbvl1#
首先,在使用
react-router
时,您必须注意以下差异。当您在浏览器中输入
localhost:3003/test/
时,它将请求服务器,然后它将接收/test/index.html
,js
捆绑包,css
...之后,每当你点击一个内部链接(如.
localhost:3003/test/t/
),您的浏览器将不会再次请求服务器。React-router
将解析此客户端,重新呈现页面的部分内容,并更新浏览器的地址栏(使用HTML5pushstate()
),而不会触发另一个服务器请求。当你直接在地址栏输入
localhost:3003/test/t/
时,你的浏览器会请求服务器,而Tomcat没有/test/t/index.html
左右,它返回一个404
。这是因为Tomcat对react-redux
和javascript
一无所知。处理此问题的一种方法是将
404
错误配置为转发到/test/index.html
。这可能是你的webpack开发服务器默认配置的方式。在apache上有很多这样的例子,如果你在我们的Tomcat面前有一个。搜索
html5 pushstate apache config
。下面是一个示例:
httpd.conf
:字符串
如果您单独使用Tomcat,您可以尝试在
web.xml
文件中指定此选项:型
请注意,这不是
react-router
特定的问题,每个使用HTML5pushstate()
的应用程序都需要以某种方式处理此问题。JavaScript服务器可以更无缝地处理这个问题。puruo6ea2#
Tomcat 8及以上版本有a simple built-in solution for this。你不需要把它放在Apache后面来处理这个问题,或者切换到哈希路由,或者破解重定向页面回到你自己的服务器上的另一个地方。
使用Tomcat Rewrite
它适用于任何具有UI路由的单页应用框架,如React,Angular,ExtJS等。
简而言之:
1)将RewriteValve添加到
/tomcat/webapps/{your-web-app-directory}/META-INF/context.xml
字符串
2)创建一个名为:
/tomcat/webapps/{your-web-app-directory}/WEB-INF/rewrite.config
,然后为您想要指向索引页的任何路径添加重写规则:型
这些规则告诉Tomcat将所有具有这三个命名路径的请求直接发送到index.html。
3)重新启动Tomcat
规则可以变得更好,比如将所有请求发送到index.html *,除了某个路径的 *,这对于
/api
调用非常有用,因为index.html
以外的其他地方。上面的链接介绍了如何使用Tomcat重写的其他示例。ijnw1ujt3#
我有同样的问题路由不工作。如果404没有重定向和加载index.html问题。我尝试了几种方法,终于找到了解决问题的方法。
这在Tomcat 8上对我很有效
字符串
你可以通过
型
在web.xml中粘贴以下内容
型
重新启动Tomcat。这为我解决了路由问题。
llew8vvj4#
我的解决方案就像是JSP引擎的一个变通方法(例如Tomcat),但它用最少的代码就能很好地工作。
我创建了一个“index.jsp”与“index.html”并行(在内容根文件夹中),代码如下:
index.jsp
字符串
我在web.xml中配置了所有URL以重定向到此JSP
web.xml
型
现在,任何请求到Tomcat的URL都将在内部重定向到index.jsp,实际上是index.html。一旦react-router加载到浏览器中,它就会负责渲染正确的组件和后续请求。
ndh0cuux5#
在我的情况下,我想要一个简单的解决方案,如创建一个客户错误页面。然而,该解决方案仍然设置了不期望的状态代码
404
。因此,我使用了一个小的jsp文件,它将在输出SPA的
index.html
之前将状态码设置为200
。我希望这可以帮助其他人寻找一个简单的解决方案,而不返回状态
404
。web.xml
字符串
spa.jsp
型
f87krz0w6#
对于Tomcat版本8以下。您只需添加一个
web.xml
文件并将404路由到index.html
。webapps/[my-app-name]/WEB-INF/web.xml
字符串
8e2ybdfx7#
在我的理解中,问题出现在多视图React应用程序中,其中路由器用于更改页面URL以反映应用程序的状态。这很好,但是如果你不小心重新加载页面,你会得到404,因为没有任何资源匹配更改后的URL。这也意味着这样改变的URL不能被标记为直接访问不同的应用程序视图。除非,我们从服务器端得到一点帮助。
根据如何处理对静态资源的访问,或者选择的实现(filter,servlet甚至JSP),可能有更多的解决方案,但基本思想是为React中定义的每个Routes提供主应用程序HTML文件。
假设你在应用程序中定义了两个React Routes:
字符串
您可以创建一个 RouterServlet 来将请求转发到/view 1或/view 2并返回到上下文根(/),假设您将应用程序Map到此处。
型
你可以这样配置它:
型
9udxz4iz8#
虽然我不熟悉Tomcat,但最有可能发生的情况是,您的服务器正在查找
/test/t
或/test/t/index.html
文件,由于不存在,因此返回404错误。当您使用浏览器历史记录时,您需要有一个可以处理路由的服务器。通常,这将是一个通配符(
*
)路由,它返回您的index.html
文件(反过来,它将返回捆绑的js以及索引文件中包含的任何其他静态文件)。一种解决方案是切换到使用哈希路由器。如果您无法在服务器上进行路由(特别是对于托管静态内容的用户而言),那么哈希路由是必要的。但是,因为你使用的是服务器,你应该能够设置路由,允许你使用浏览器路由器。
正如我之前所说的,我不熟悉Tomcat,所以我只描述一下应该是什么配置。
1.所有静态文件的请求都应定期提供。
1.所有其他对
/test/*
的请求(其中 * 是任何URL)都应该服务于您的index.html
文件。yptwkmov9#
对于那些在嵌入式Tomcat服务器上使用springboot的人来说,解决方案相当简单。我努力了很久才来到这里,但希望这能帮助到别人。
这是基于上面的@rafael-z响应。
我们只需要利用springboot提供的错误处理-在一些Springbean中添加以下内容
字符串