详解react-router 4.0 下服务器如何配合BrowserRouter


Posted in Javascript onDecember 29, 2017

react-router作为react框架路由解决方案在react项目中举足轻重。

在react-router 4.0版本中,API与先前版本相比有了很大的修改,在2.0、3.0中常用的<Router>组件作为路由底层配置组件不再常用,取而代之的是四个各有不同的路由组件:

<BrowserRouter>, <HashRouter>, <MemoryRouter>, <StaticRouter>

其中<MemoryRouter>组件在内存中保存“URL”信息,不会修改浏览器的地址栏,往往用于React Native或测试环境等非浏览器环境。

而<StaticRouter>组件从名字能看出它从不修改路由,这在服务器端渲染时很有用。

<HashRouter>组件我们最为熟悉的路由组件不用再多赘述,这里来说说我在使用react-router推荐的<BrowserRouter>时遇到的坑。

<BrowserRouter>

<BrowserRouter>和<HashRouter>都可以实现前端路由的功能,区别是前者基于rul的pathname段,后者基于hash段。

前者:http://127.0.0.1:3000/article/num1

后者:http://127.0.0.1:3000/#/article/num1(不一定是这样,但#是少不了的)

这样的区别带来的直接问题就是当处于二级或多级路由状态时,刷新页面,<BrowserRouter>会将当前路由发送到服务器(因为是pathname),而<HashRouter>不会(因为是hash段)。

我们当然不希望前端路由被发送到后台。

在react-router 4.0 的文档中有这样一段话:

注意: 使用 hash 的方式记录导航历史不支持 location.key 和 location.state。 在以前的版本中,我们为这种行为提供了 shim,但是仍有一些问题我们无法解决。 任何依赖此行为的代码或插件都将无法正常使用。 由于该技术仅用于支持传统的浏览器,因此在用于浏览器时可以使用 <BrowserHistory> 代替。

这就要求服务器要配合前端做一些简单的修改。

修改的思想就是当收到请求的url不是功能性的,而是前端路由时,重新加载入口html文件(我的后台是nodejs)。

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  //判断是主动导向404页面,还是传来的前端路由。
 //如果是前端路由则如下处理

  fs.readFile(__dirname + '/public/dist/index.html', function(err, data){
    if(err){
      console.log(err);
      res.send('后台错误');
    } else {
      res.writeHead(200, {
        'Content-type': 'text/html',
        'Connection':'keep-alive'
      });
      res.end(data);
    }
  })
});

此处踩坑无数,在网上搜索方法后换用nginx,使用try_files字段定向到入口html,但是重定向后,webpack打包的js文件没有执行。

在查看firebug时发现此次刷新的响应头中设置了"Connection":"keep-alive";

觉得问题应该出在这里,换用nodejs用200状态配合keep-alive果然解决了问题。

在react-router 4.0 多级路由下刷新页面不会再404,而是保存了前端状态。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript学习笔记(五)正则表达式
Apr 08 Javascript
js change,propertychange,input事件小议
Dec 20 Javascript
jQuery滚动条插件nanoscroller使用指南
Apr 21 Javascript
Angular的$http与$location
Dec 26 Javascript
Javascript 实现计算器时间功能详解及实例(二)
Jan 08 Javascript
JavaScript如何一次性展示几万条数据
Mar 30 Javascript
jquery与js实现全选功能的区别
Jun 11 jQuery
详解angularjs 学习之 scope作用域
Jan 15 Javascript
微信小程序实现弹出菜单功能
Jun 12 Javascript
微信小程序授权登录及解密unionId出错的方法
Sep 26 Javascript
Vue实现一个图片懒加载插件
Mar 11 Javascript
小程序wx.getUserProfile接口的具体使用
Jun 02 Javascript
浅谈react-router HashRouter和BrowserRouter的使用
Dec 29 #Javascript
javaScript 连接打印机,打印小票的实例
Dec 29 #Javascript
深入浅析vue组件间事件传递
Dec 29 #Javascript
详解Vue 事件修饰符capture 的使用
Dec 29 #Javascript
react-router browserHistory刷新页面404问题解决方法
Dec 29 #Javascript
node简单实现一个更改头像功能的示例
Dec 29 #Javascript
JavaScript 中使用 Generator的方法
Dec 29 #Javascript
You might like
用PHP实现ODBC数据分页显示一例
2006/10/09 PHP
PhpDocumentor 2安装以及生成API文档的方法
2014/05/21 PHP
php实现的ping端口函数实例
2014/11/12 PHP
PHP执行SQL文件并将SQL文件导入到数据库
2015/09/17 PHP
Extjs Ajax 乱码问题解决方案
2009/04/15 Javascript
某页码显示的helper 少量调整,另附js版
2010/09/12 Javascript
javascript中的window.location.search方法简介
2013/09/02 Javascript
js隐式全局变量造成的bug示例代码
2014/04/22 Javascript
jquery+html5烂漫爱心表白动画代码分享
2015/08/24 Javascript
JavaScript原生对象常用方法总结(推荐)
2016/05/13 Javascript
JavaScript对Json的增删改属性详解
2016/06/02 Javascript
jquery对象和DOM对象的相互转换详解
2016/10/18 Javascript
基于js实现的限制文本框只可以输入数字
2016/12/05 Javascript
JavaScript对象引用与赋值实例详解
2017/03/15 Javascript
vue.js选中动态绑定的radio的指定项
2017/06/02 Javascript
基于jquery实现九宫格拼图小游戏
2018/11/30 jQuery
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
2019/04/26 Javascript
python迭代器与生成器详解
2016/03/10 Python
Python标准库之itertools库的使用方法
2017/09/07 Python
python SSH模块登录,远程机执行shell命令实例解析
2018/01/12 Python
Python实现PS滤镜的万花筒效果示例
2018/01/23 Python
阿里云ECS服务器部署django的方法
2019/08/29 Python
python程序 创建多线程过程详解
2019/09/23 Python
python 实现dict转json并保存文件
2019/12/05 Python
Python TCPServer 多线程多客户端通信的实现
2019/12/31 Python
Tensorflow训练模型越来越慢的2种解决方案
2020/02/07 Python
美国帽子俱乐部商店:Hat Club
2019/07/05 全球购物
俄罗斯三星品牌商店:GalaxyStore
2020/11/04 全球购物
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
财务会计专业推荐信
2013/11/30 职场文书
《会走路的树》教后反思
2014/04/19 职场文书
小学生竞选班干部演讲稿
2014/04/24 职场文书
2014年统战工作总结
2014/12/09 职场文书
餐饮服务食品安全承诺书
2015/04/29 职场文书
七年级数学教学反思
2016/02/17 职场文书
同学聚会开幕词
2019/04/02 职场文书