React 中的 HashRouter 和 BrowserRouter 有啥区别?

Posted

技术标签:

【中文标题】React 中的 HashRouter 和 BrowserRouter 有啥区别?【英文标题】:What is the difference between HashRouter and BrowserRouter in React?React 中的 HashRouter 和 BrowserRouter 有什么区别? 【发布时间】:2019-01-29 03:48:10 【问题描述】:

我是编程新手,如果我阅读官方文档,这会让我有点难以理解。

我正在阅读关于React Router 4 from here

在这篇文章中,作者谈到了<HashRouter><BrowserRouter>

这是他提到的:

HashRouter 基本上它使用 URL 中的哈希来呈现组件。由于我正在构建一个静态的单页网站,所以我需要使用它。

BrowserRouter,它使用 html5 历史 API 来渲染组件。历史可以通过 pushState 和 replaceState 进行修改。更多信息可以在这里找到

现在,我不明白两者的意义和用例,就像他说 历史可以通过 pushState 和 replaceState 修改并且 它使用哈希渲染组件的 URL

虽然第一个对 BrowserRouter 的解释对我来说完全是模糊的,但关于 HashRouter 的第二个解释也没有意义,比如为什么有人会在 url 中使用 Hash (#) 来渲染组件?

【问题讨论】:

developer.mozilla.org/en-US/docs/Web/API/History_API 您没有为现有答案提供反馈。由于他们已经直接回答了这个问题,因此有必要澄清这个问题需要什么样的关注。 评论***.com/questions/56707885/…参考官方文章techiediaries.com/react/react-router-5-4-tutorial-examples/…。 “如果您使用的是可以处理动态 URL 的动态服务器,那么您需要使用 BrowserRouter 组件,但如果您使用的服务器仅提供静态文件,那么在这种情况下将使用 HashRouter 组件。” 【参考方案1】:

BrowserRouter

它使用history API,即它不适用于旧版浏览器(IE 9 及更低版本和同时代的浏览器)。客户端 React 应用程序能够像 example.com/react/route 一样维护干净的路由,但需要 Web 服务器支持。通常这意味着应该为单页应用程序配置 Web 服务器,即为 /react/route 路径或服务器端的任何其他路由提供相同的 index.html。在客户端,window.location.pathname 由 React 路由器解析。 React 路由器渲染一个它被配置为为 /react/route 渲染的组件。

此外,设置可能涉及服务器端渲染,index.html 可能包含渲染组件或特定于当前路由的数据。

HashRouter

它使用 URL 哈希,它对支持的浏览器或 Web 服务器没有任何限制。服务器端路由独立于客户端路由。

向后兼容的单页应用程序可以将其用作example.com/#/react/route。服务器端渲染无法备份设置,因为它是在服务器端提供的 / 路径,#/react/route URL 哈希无法从服务器端读取。在客户端,window.location.hash 由 React 路由器解析。 React 路由器渲染它配置为为 /react/route 渲染的组件,类似于BrowserRouter

最重要的是,HashRouter 用例不仅限于 SPA。一个网站可能有遗留或搜索引擎友好的服务器端路由,而 React 应用程序可能是一个在 URL 中维护其状态的小部件,例如 example.com/server/side/route#/react/route .一些包含 React 应用程序的页面在服务器端为 /server/side/route 提供服务,然后在客户端 React 路由器呈现一个它被配置为为 /react/route,类似于之前的场景。

【讨论】:

另外一点 - 如果您需要在页面上进行锚点导航(location.hash 通常是为开箱即用而设计的),实现起来有点困难。 @iRohitBhatia BrowserHistory 还允许您进行服务器端渲染,因为服务器可以访问完整的 URL。服务器无权访问#后面的路径。【参考方案2】:

服务器端: HashRouter 在 URL 中使用井号,这具有在服务器请求中忽略所有后续 URL 路径内容的效果(即您发送“www.mywebsite.com/# /person/john" 服务器获取 "www.mywebsite.com"。因此服务器将返回 pre # URL 响应,然后 post # 路径将由您的客户端 react 应用程序处理(或解析)。

客户端: BrowserRouter 不会将 # 符号附加到您的 URL,但是当您尝试链接到页面或重新加载页面时会产生问题。如果显式路由存在于您的客户端 react 应用程序中,但不在您的服务器上,则重新加载和链接(任何直接访问服务器的内容)将返回 404 not found 错误。

【讨论】:

【参考方案3】:

刷新页面会导致浏览器使用当前路由向服务器发送 GET 请求。 # 用于阻止我们发送该 GET 请求。我们使用 BrowserRouter 因为我们 希望将 GET 请求发送到服务器。为了在服务器上渲染路由器,我们需要一个 位置——我们需要路线。该路由将在服务器上用于告诉路由器要渲染什么。 当你想同构渲染路由时使用 BrowserRouter。

【讨论】:

最重要的是要注意。 你是说HashBrowser只能被SPA(单页应用)使用,而BrowserRouter可以被SPA和多页应用(从服务器返回的不同页面)使用?【参考方案4】:

BrowserRouterHashRouter 组件都作为 Router 类的子类在 React Router 版本 4 中引入。简单地说,BrowserRouter 将 UI 与浏览器中的当前 URL 同步,这是通过 HTML-5 History API 完成的。另一方面,HashRouter 使用 URL 的 Hash 部分进行同步。

【讨论】:

【参考方案5】:

“用例”

HashRouter:当我们有不需要后端的小型客户端应用程序时,我们可以使用HashRouter,因为当我们在 URL/位置栏浏览器中使用哈希时,不会发出服务器请求.

BrowserRouter:当我们有大型生产就绪应用程序提供后端服务时,建议使用<BrowserRouter>

书籍参考:学习 React:使用 React 和 Redux 进行功能性 Web 开发 作者:Alex Banks、Eve Porcello

【讨论】:

恕我直言,“HashRouter”与“BrowserRouter”与“小型”与“大型生产就绪”应用程序无关。在大型生产就绪应用程序中使用 HashRouter 既没有限制也没有性能问题。这一切都与特定的用例、需求和最终的架构有关。无服务器生产应用程序是真实存在的。 你的意思是“小”SPA(单页)应用程序,并告诉BrowserRouter可以被多页应用程序使用?【参考方案6】:

选择“哈希路由器”而不是“浏览器路由器”的主要用例场景是在生产环境中。假设我们有这个网址“www.example.com/Example”。在这种情况下,一些服务器倾向于按名称“示例”搜索文件夹并最终返回 404,因为我们有单页应用程序 index.html。因此,为了避免这种混淆,我们使用“www.example.com/#/Example”。这就是哈希路由器大放异彩的地方。

资源:https://www.techblogsnews.com/post/browser-router-vs-hash-router-in-react-js

【讨论】:

【参考方案7】:

我想再添加一个用例。 在使用 BrowserRouter 或 Router 时,它可以在我们的节点服务器上正常工作。因为它理解客户端路由(预配置)。

但是当我们在 Apache 服务器上部署我们的构建 React 应用程序时(只是说 php,在 GoDaddy 上),然后路由将无法按预期工作。它将进入 404,为此我们需要配置 .htaccess 文件。之后对我来说,每次点击/url,它都会向服务器发送请求。

在这种情况下,我们最好使用 HASH 路由 (#)。 # 我们在 html 页面上使用它,用于遍历 HTML 内容,它不会导致服务器请求。

在上面的场景中我们可以使用HashRouting,即所有出现在#之后的url,我们可以将我们的路由规则作为SPA来工作。

【讨论】:

【参考方案8】:

评论BrowserRouter vs Router with history.push()指文章https://www.techiediaries.com/react/react-router-5-4-tutorial-examples/#React_Router_5_Routers_BrowserRouter_vs_HashRouter

“如果您使用的是可以处理动态 URL 的动态服务器,那么 您需要使用 BrowserRouter 组件,但如果您使用的是 仅提供静态文件的服务器,然后是 HashRouter 组件 在这种情况下使用什么”

HashRouter重新历史的限制

我之前误解了https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.mdHashRouter 文章顶部的注释

由于该技术仅用于支持旧版浏览器,因此我们 鼓励您配置您的服务器以使用 BrowserHistory 而是。

通常不鼓励使用 HashRouter,但作者不建议仅在需要对 location.key 或 location.state 的支持时使用 HashRouter。

【讨论】:

【参考方案9】:

基本上,如果使用 BrowserRouter,则可以使用诸如“soAndSoReactPage/:id”之类的 url

例如:

with a Route <Route path="soAndSoReactPage/:id"><soAndSoReactComponent/></Route>

现在,在反应组件“soAndSoReactComponent”中 然后可以使用 useParams 提取“id”,因此您可以根据 id 显示页面“soAndSoReactComponent”

这样的事情用HashedRouter是做不到的,

【讨论】:

不,它对 BrowserRouter 和 HashRouter 都有效。 哈希历史无法推送状态,被忽略。但路径参数正在工作。

以上是关于React 中的 HashRouter 和 BrowserRouter 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

react-router-dom中的BrowserRouter和HashRouter

react-router-dom中的BrowserRouter和HashRouter

react-router-dom中的BrowserRouter和HashRouter

React 学习之路由HashRouter和BrowserRouter

React Router 的 HashRouter 重定向到 <base> 标签 url

如何使用 React HashRouter 和 Apollo 客户端渲染反应类组件?