react 的 browserHistory 模式,服务器不配置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react 的 browserHistory 模式,服务器不配置相关的知识,希望对你有一定的参考价值。

参考技术A

SPA 项目基本上都会用到路由 router。react 还有 vue 对应有其路由插件。 react-router 还有 vue-router 都有 hashHistory 和 browserHistory 模式。这里大概说一下两者区别

大多数情况下,browserHistory 模式明显是优于 hashHistory 模式的,但 browserHistory 需要一定的配置

可以看出,hashHistory 不需要什么配置,但 browserHistory 需要服务端支持,这里简单说一下两种方式做支持,其它方式基本上都是类似

这里说明一下为什么要这样设置,browserHistory 模式下,URL 是指向真实 URL 的资源路径,当通过真实 URL 访问网站的时候(首页),这个时候可以正常加载我们的网站资源,而用户在非首页下手动刷新网页时,由于路径是指向服务器的真实路径,但该路径下并没有相关资源,用户访问的资源不存在,返回给用户的是 404 错误

通过上面所说的原理,简单起来说就是 browserHistory 模式下,需要每个路由下都要有对应的资源存在,就不会产生 404 错误,所以如果不借助服务端的话,又要实现这种模式,这种场景在自己不能配置服务器时候会碰到,例如把项目部署到 GitHub pages 上。那该怎么办呢

所以,我们的做法就是在每个 路由路径 下,都放置一个跟首页一样的 index.html

下面是做法,当然也是有各种方式的,都是可以类推的

假定我们有以下的路由设定,这里以 react-router 为例子

那么就可以路由路径为

接下来我们就把生成的 index.html 复制到这几个路径下就可以了

这样用户访问就不会出现 404 了,SPA 的功能也不受影响,为了方便我们可以把这个生成工具集成到 package.json

ok, 当我们运行 npm run build 时候,就会同时生成对应路径下的 index.html,这样就可以了完成我们所需要的功能了

看到这里,应该会有一个疑问,如果 routes 中有一些是不能穷举的路径要怎么办?例如 <Route path="posts/:id" component=Verify(Inbox) /> 。这时候是没办法生成对应资源的

不过还是可以使用以下 hack 方式:

直接使用服务端 404 页面了,如果是用 GitHub pages 的话,我们可以直接生成一个 404.html 即可,直接把 404 页面弄成跟 index 内容一样,404 时候就是正常的内容页面,这时候页面功能是正常的,并且不需要前面的一堆做法了.

React 路由器 - BrowserHistory.Push VS。上下文类型

【中文标题】React 路由器 - BrowserHistory.Push VS。上下文类型【英文标题】:React Router - BrowserHistory.Push VS. ContextTypes 【发布时间】:2017-03-08 05:28:18 【问题描述】:

我正在完成一个高级 react/redux 教程,并在课程中遇到了讲师使用 browserHistory.push 链接到路由的部分,而不是之前用于创建名为 contextTypes 的静态类变量的方法并将其设置为类似于 React.PropTypes.blah blah blah。

这和使用 browserHistory.push 有什么区别? browserHistory.push 作为程序化重新路由似乎比设置上下文类型要容易得多。

谢谢!

【问题讨论】:

【参考方案1】:

不确定您使用了哪些教程,所以这有点摸不着头脑。

我想您在第一个教程中使用了类似https://github.com/reactjs/react-router-redux 的东西,将路由器状态与您的 redux 状态同步,并将您的路由器对象放在上下文中。然后您可以执行以下操作:

this.context.router.push(location) 发送位置更改 这会将位置更改保存到您的 redux 状态,然后加载该新路由。

在核心 react-router-redux(以及许多其他路由库)使用 https://github.com/ReactTraining/history 来管理导航到的路由的历史记录。这允许您在现代浏览器中使用 HTML5 历史 API,回退到 hashHistory (index.html/#page-one) 或内存历史,即呈现服务器端。

history 包带有它自己的 API。在您的教程中,browserHistory.push() 可能会直接调用历史包的 API (see here)。

这将导致应用加载新路由,但可能会绕过同步到您的 redux 存储。

您的第二个教程可能不使用 react-router-redux 或有不同的设置。

【讨论】:

以上是关于react 的 browserHistory 模式,服务器不配置的主要内容,如果未能解决你的问题,请参考以下文章

react-router v2.0 的打字稿定义-错误`没有导出的成员'browserHistory'`

react路由器中的hashHistory和browserHistory有啥区别?

[React] React Router: hashHistory vs browserHistory

react-router v4 - browserHistory 未定义

React-router 配置browserHistory

React-Router:将我的 url 从 hashHistory 重定向到 browserHistory