当 URL 不匹配任何路由并且 URL 包含 /#/ 时如何使用 ReactJS 显示 404
Posted
技术标签:
【中文标题】当 URL 不匹配任何路由并且 URL 包含 /#/ 时如何使用 ReactJS 显示 404【英文标题】:How to display 404 when URL doesn't match any route and when the URL contains /#/ using ReactJS 【发布时间】:2018-06-28 22:48:41 【问题描述】:这是我第一次使用 ReactJS 并且不是我的项目,但是我正在尝试将任何不存在的路由重定向到我制作的 404 页面。当 URL 包含 /#/
时输入任何与路由不匹配的 URL 除了,我的 404 页面当前正在按预期显示。
比如这个网址会重定向到我的404页面:
http://localhost:8080/non-existent-url
但是这个 URL 只会加载我应用的默认路由(主页):
http://localhost:8080/#/non-existent-url
我不知道/#/
是做什么用的,看来该应用程序将显示带有或不带它的有效路线的页面。
精简路线文件:
import React from "react";
import Router, Route, IndexRoute, browserHistory, hashHistory, Redirect from "react-router/es";
import willTransitionTo from "./routerTransition";
import App from "./App";
import DashboardContainer from "./components/Dashboard/DashboardContainer";
import DashboardAccountsOnly from "./components/Dashboard/DashboardAccountsOnly";
import NotFound from './components/NotFound';
const history = __HASH_HISTORY__ ? hashHistory : browserHistory;
class Auth extends React.Component
render() return null;
const routes = (
<Route path="/" component=App onEnter=willTransitionTo>
<IndexRoute component=DashboardContainer/>
<Route path="/auth/:data" component=Auth/>
<Route path="/dashboard" component=DashboardContainer/>
<Route path='*' exact=true component=NotFound />
</Route>
);
export default class Routes extends React.Component
render()
return <Router history=history routes=routes />;
404(未找到)组件:
import React from 'react';
import Link from "react-router/es";
import Translate from "react-translate-component";
var image = require("assets/404.png");
const NotFound = () =>
<div className="grid-block main-content wrap regular-padding">
<div className="grid-content small-12" style=marginTop:"200px">
<div style= textAlign:"center">
<img style=marginBottom:"1.2rem" src=image />
<h3>404 page not found</h3>
<p>This page does not exist.</p>
<Link className="button" to="/dashboard">
<Translate style=color:"#fff" content="account.home" />
</Link>
</div>
</div>
</div>
export default NotFound;
当 URL 不匹配任何路由并且当 URL 包含 /#/
时,我如何将用户重定向到我的 404 页面?
【问题讨论】:
你使用的是哪个版本的 React Router? 您可能想阅读 React Router 文档中的browserHistory
而不是hashHistory
像const history = browserHistory;
@MattD 我正在使用 react-router v3.0.2。我尝试了 Shubham 的建议,但没有任何区别。
Please check here。它会帮助你。
【参考方案1】:
对于 react-router
如果你想显示错误页面而不改变路径
<Route path='*' exact=true component=errorcomponent />
如果要显示错误页面并更改路径
<Route path='/error' component=errorcomponent />
// use redirect to change the Url
<Redirect from='*' to='/error' />
对于反应路由器 4
保持路径
<Switch>
<Route exact path="/" component=component />
<Route component=errorcomponent />
</Switch>
更改网址。
<Switch>
<Route path="/comp" component=component />
<Redirect to="/error" />
</Switch>
无论您在交换机中放置路由标签的任何位置,都必须放置重定向标签。
【讨论】:
这究竟如何解决处理带有 /#/ 的路由的问题?请详细说明这一点。另外,我认为您没有为 v4 示例正确设置重定向,或者您提供的示例不完整。【参考方案2】:根据我在您的代码中看到的内容,尝试在哈希历史记录和浏览器历史记录之间切换是行不通的。当您在任何会中断的地方点击“/#”时,总是会点击您的通用“/”路线。
哈希 URL 是一种处理不再是问题的旧方法。有关更多详细信息,请参阅此 SO 问题及其接受的答案。
Doing links like Twitter, Hash-Bang #! URL's
所以是的,除非你有一些疯狂的理由仍然支持 URL 中的哈希,否则删除哈希历史并简单地使用浏览器历史。然后,您在提供的代码示例中定义的路线应该可以工作。
【讨论】:
这个答案是否仍然适用,即使它在技术上不是一个哈希爆炸(没有'!')?我从路由文件中删除了对 hashHistory 的所有引用,但不存在的 URL 仍然路由到应用主页,而不是 404。 @dom_ahdigital 我会说您设置路由的方式在某些方面不正确,或者它是另一个导致您的全部路径不被命中的项目。查看您的 React Router 版本的所有文档,以确保您设置正确(这可能会有所帮助:github.com/ReactTraining/react-router/blob/v3/docs/guides/…)。除此之外,如果实际上没有什么需要您坚持使用 3.0.2,我会考虑简单地升级到最新版本。 @dom_ahdigital 另外,澄清一下,您还没有尝试使用/#/non-existant-url
是吗?【参考方案3】:
您可以访问location.hash 值并将其设置为空白。
但正如已经很好地描述的那样,这是多年来的标准 http,除非有充分的理由,否则您不应该关心。
你可以看到它像http://localhost:8080/?non-existent-url
这意味着去/
带有路径参数non-existent-url
你也想重定向吗?
【讨论】:
【参考方案4】:在创建 URL 时应该避免一些不安全的字符,其中之一是#
。
字符“#”是不安全的,应始终进行编码,因为它是 在万维网和其他系统中用于将 URL 与 可能跟随它的片段/锚标识符。
服务器在解析路由时将传递#
之前的字符串以获取请求的页面,然后如果使用#
之后的字符串指定任何内容,它将移动页面的确切片段,直到出现任何不安全字符。
所以,在#
之前的字符串中为空,这就是它重定向到/
的原因,这是一个有效的路由,它重定向到component App
。而且由于没有定义片段,所以什么也没发生。
为了使这个工作我们需要告诉nginx or any other server
在发送请求前删除所有#
。
在这种情况下,
http://localhost:8080/#/non-existent-url
将转换为,
http://localhost:8080/non-existent-url
这将解决问题。 看这个链接看How to rewrite rule in nginx
【讨论】:
鉴于我无法安全更新的旧版本 react 路由器的情况,我将不得不使用 URL 重写。【参考方案5】:你可以用这个
<Route exact insecure component=NotFound />
【讨论】:
您能否提供更多解释,说明为什么这是解决问题的解决方案? 这不起作用,产生完全相同的结果。【参考方案6】:问题在于,在 URL http://localhost:8080/#/non-existent-url 中,路由只是 /,这就是它访问您的应用程序组件的原因。标准 URL 中 # 的意图意味着转到页面中的某个位置。因此,您的 url 是说“加载页面后转到 / 页面并转到此特定位置”。
从路由的角度来看,/是你的路由,所以它被找到了。老实说,如果您没有使用 5 年前的 hash-bang 风格的路由,那么这就是预期的行为。在那种情况下(如果你被那些为这类页面或其他东西添加书签的人所困扰)强制这样的东西“找不到”,我会重新编写 URL。
SPA 应用程序已经在服务器上重写了传入的 URL,因此它们都指向一个页面。添加一个规则,作为重写的一部分,它会删除 #(如果您不在应用中使用它)。
因此,http://localhost:8080/#/non-existent-url 将在应用程序内部作为http://localhost:8080/non-existent-url 处理。
【讨论】:
【参考方案7】:您应该将Router
组件作为Route
s 的父组件并添加此路由
<Route path='*' component=() => NotFound />
const routes = (
<Router>
<div>
<Route path="/" component=App onEnter=willTransitionTo
<IndexRoute component=DashboardContainer/>
<Route path="/auth/:data" component=Auth/>
<Route path="/dashboard" component=DashboardContainer/>
<Route path='*' component=() => NotFound />
</div>
</Router>
);
【讨论】:
以上是关于当 URL 不匹配任何路由并且 URL 包含 /#/ 时如何使用 ReactJS 显示 404的主要内容,如果未能解决你的问题,请参考以下文章
当 url 匹配相同的路由时,vue3 router.push 不更新组件?
当 url 匹配相同的路由时,React 路由器不会重新加载页面