一, 问题描述
在一场面试中, 面试官问到了 React 和 Node 路由之间的关系.
现在 SPA(单页面应用)的使用越来越广.
Node(后台)和 React(前端)都有自己的路由, 当我页面访问一个 URL 的时候, 其中的路由究竟是以哪个为准呢?
答案是 Node 路由优先级更高
所以会经常出现 React 设置了 Router, 但刷新访问的时候就出现了 404.
因为当你刷新一个 URL 时, 首先会在 node 中识别是否存在这个路由, 因为我们并没有设置这个路由(仅仅在 React 中设置了而已), 所以会出现 Can't not GET /xxx
二, 解决方法
可能想到既然是 Node 先处理 url, 那我保证 Node 和 React 的路由都一致不就行了! 这样既不错报错也能执行 React 的路由了.
貌似确实行得通! 但是这样不仅麻烦, 而且官方不建议!
下面提供部分方法可以解决大部分简单的情况:
2.1 Node(express/koa)只渲染 html
这个是我最经常使用的方式
- var express = require('express');
- var router = express.Router();
- /* GET home page. */
- router.get('/', function(req, res, next) {
- res.render('index');
- });
用 webpack 打包 (也可以不打包) 后, 在根 HTML 模板里引入相关的 JS, 然后 node 用根路径 / 去匹配该 HTML 模板. 这样无论如何 node 都不会报 404 了
2.2 在 node 返回 404 的时候, 指向 HTML
- router.get('*',(ctx, next) => {
- ctx.type = 'html';
- ctx.body = fs.createReadStream('./index.html');
- });
2.3 选择合适的路由方式
hashRouter: hash 路由会挂在服务端所有路由到前端
BrowserRouter: history 模式 (BrowserRouter: 浏览器路由) 改变 url 的方式会导致浏览器向服务器发送请求, 如果匹配不到任何静态资源, 则应该始终返回同一个 HTML 页面.
比如下面两个图的对比:
histroy 模式(BrowserRouter)
hash 模式
图片来源于《react.JS 的两种路由方式: HashRouter》
可以看到 hash 路由解决了这个问题, 但是 hash 路由多了一个丑丑的 /#/
使用 hashHistory 时, 因为有 # 的存在, 浏览器不会发送 request,react-router 自己根据 url 去 render 相应的模块.
三, 后续
当然, 路由的选择不仅仅局限于此, 还包括是否需要按需加载, 路由参数使用等等.
后面会解释一下为什么 hash 路由路径上会出现这么多的哈希值, 并且出现的原因和作用是什么?
react-route 底层的一些原理和详细的用法可以参考这篇文章:
《
深入理解 react-router 路由系统》
来源: https://www.cnblogs.com/soyxiaobi/p/9786927.html