react-router 之 HashRouter & BrowserRouter

 发布 : 2018-10-16  字数统计 : 824 字  阅读时长 : 3 分  分类 : react  浏览 :

React-Router

关于 React-Router v4 版本的两种路由方式 HashRouter , BrowserRouter

1
2
BrowserRouter : http://localhost:3000/abc/def
HashRouter: http://localhost:3000/#/abc/def //hash地址就是指#号后面的url

BrowserRouter 基于 url 的 pathName 字段, HashRouter 则基于 hash 段。

问题

采用 BrowserRouter 写法

1
2
3
4
<BrowserRouter>
<Route exact path="/" component={Index}/>
<Route path="/Search" component={Search}/>
</BrowserRouter>

开发时正常,打包后的静态页面空白, 访问时无法访问。

  1. 查看发现静态资源引用异常,修改静态资源引用,改为相对路径,本身是 /static/js -> ./static/js
    在package.json文件中添加homepage字段并设置为”.” || 直接修改生成后的静态页面引用。
  2. 发现静态资源正常,但是页面还是加载不到。
  3. 改为 HashRouter 可以访问。

原因

  1. HashRouter
    hashHistory 使用URL中的hash(#)部分去创建路由.
    举例来说,用户访问 /search, 实际会看到的是 http://localhost:3000/#/search 加载对应组件。
    访问 /(http://localhost:3000/#/)时 加载对应组件。

  2. BrowserRouter
    browserHistory 是使用 React-Router 的应用推荐的 history方案。它使用浏览器中的 History API 用于处理 URL.创建一个真实的URL.
    在 browserHistory 模式下,URL 是指向真实 URL 的资源路径。
    当通过真实 URL 访问网站的时候,由于路径是指向服务器的真实路径,但并没有对应物理路径/文件 ,实际所有内容是通过React-Router去渲染React组件,
    所以用户访问的资源不存在,则空白。

解决

  1. 采用 HashRouter–开发时可以,打包后的页面访问也可用。
  2. 采用 BrowserRouter—开发时可以,打包后的页面不可直接访问。
    本地开发时可以通过配置 webpack-devServer 的 historyApiFallback,create-react-app 已配置。
  3. 采用 BrowserRouter–服务端支持
1
2
3
4
5
6
7
8
9
10
server {
server_name react.com;
listen 80;

root /user/src/React-Demo/dist;
index index.html;
location / {
try_files $uri /index.html;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var express = require('express');
var path = require('path');
var app = express();

//设置静态资源目录
app.use(express.static(path.join(__dirname, './build')));

//所有访问,都指定返回 index.html
//而index.html会根据React-Router规则去匹配任何一个route
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, './build', 'index.html'));
});

//设置服务器
var server = app.listen(3001, function () {
var host = server.address().address;
var port = server.address().port;
console.log('众享后台 listening at http://%s:%s', host, port);
});

补充

  1. create-react-app 本地开发时使用 BrowserRouter 可以支持(webpack服务器-已配置)。
  2. 设置代理到 node 服务器时,注意是以 /api/ 开头
  3. 若路径中含有 /api/, 上步没有设置开头,则页面被转发到 node 服务器。
    返回的虽然设置了 index.html, 但是加载对应 index.html 中的静态资源的时候,返回的也是页面,不是静态资源。
    如果资源返回正常,页面是可以正常加载的,因为只要都返回静态页面,具体路由是有对应js处理的。
1
2
3
4
5
6
"proxy": {
"^/api/": {
"target": "http://localhost:3001",
"changeOrigin": true
}
},
留下足迹