react-router v4中 HashRouter 和 BrowserRouter的使用

遇到的问题

项目中控制路由跳转使用的是BrowserRouter,代码以下:html

ReactDOM.render((
    <BrowserRouter>
        <div className="container">
            <Route path={routePaths.INDEX} exact component={Index} />
            <Route path={routePaths.CARD} component={Card} />
            <Route path={routePaths.BASEINFO} component={BaseInfo} />
            <Route path={routePaths.EDUINFO} component={EduInfo} />
            <Route path={routePaths.FAMILYINFO} component={FamilyInfo} />
            <Route path={routePaths.OTHERINFO} component={OtherInfo} />
            <Route path={routePaths.DETAIL} component={Detail}/>
        </div>
    </BrowserRouter>
    ),
    document.getElementById('app')
);

在开发过程当中使用是没有问题的,可是将页面上传至服务器以后,问题就来了:用户访问的资源不存在,页面是空白的。 通过排查怀疑是路径的问题,将BrowserRouter 改成 HashRouter以后,问题解决了~react

问题分析

首先分析下出现此问题的缘由: 在React项目中咱们常常须要采用React-Router来配置咱们的页面路由,React-Router 是创建在 history 之上的,常见的history路由方案有三种形式,分别是:webpack

  • hashHistory
  • browserHistory
  • createMemoryHistory

hashHistory 使用 URL 中的 hash(#)部分去建立路由,举例来讲,用户访问http://www.example.com/,实际会看到的是http://www.example.com/#/。git

<HashRouter>
        <div className="container">
            <Route path='/repos' component={Repos} />
            <Route path='/about' component={About} />
        </div>
    </HashRouter>

上面代码中,用户访问/repos(好比http://localhost:8080/#/repos)时,加载Repos组件;访问/about(http://localhost:8080/#/about)时,加载About组件。github

browserHistory 是使用 React-Router 的应用推荐的 history方案。它使用浏览器中的 History API 用于处理 URL,建立一个像example.com/list/123这样真实的 URL 。web

在browserHistory 模式下,URL 是指向真实 URL 的资源路径,当经过真实 URL 访问网站的时候,因为路径是指向服务器的真实路径,但该路径下并无相关资源,因此用户访问的资源不存在。浏览器

Memory history 不会在地址栏被操做或读取。这就解释了咱们是如何实现服务器渲染的。同时它也很是适合测试和其余的渲染环境(像 React Native )。和另外两种history的一点不一样是你必须建立它,这种方式便于测试。服务器

const history = createMemoryHistory(location)

解决办法

  • 使用hashHistory

本地开发时,使用browserHistory是没有问题的,这是由于webpack.config.js中使用 webpack-dev-server 已经作了配置。react-router

 webpackConfig.devServer = {
        contentBase: path.resolve(__dirname, 'build'),
        compress: true, //gzip压缩
        historyApiFallback: true,
    };
  • 若是要使用browserHistory的话,服务器须要进行相关路由配置,方法见 这里

参考资料:app

  1. https://www.sitepoint.com/react-router-v4-complete-guide/
  2. http://react-guide.github.io/react-router-cn/docs/guides/basics/Histories.html
  3. https://www.thinktxt.com/react/2017/02/26/react-router-browserHistory-refresh-404-solution.html
  4. http://echizen.github.io/tech/2016/07-05-webpack-dev-server-react-router-config
  5. https://jaketrent.com/post/pushstate-webpack-dev-server/
相关文章
相关标签/搜索