前两节课的路由内容中,我们发现一旦刷新页面,就会出现类似404的页面,表示找不到此页面。

这是为什么呢?

这其实和路由的原理,浏览器的 HTML5 History API 有关。先来试试下面的内容:

注意,如果直接打开静态页面 file:///C:/Users/lizhaohong/Desktop/test_history.html 是没有效果的。

必须在服务器部署的环境下打开才可以使用,如 http://localhost:8080/test_history.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>    
</head>
<body>
<button onclick="updateUrl('abc')" >abc</button>
<button onclick="updateUrl('efg')" >efg</button>
<button onclick="history.back()">回退</button>
<button onclick="history.forward()">前进</button>
<script>
    // 使用 HTML5 History API  修改浏览器地址
    var updateUrl = function (path) {
        let state = {
            url: path,
            name: "fuckyou"
        };
        history.pushState(state, null, path);
    }

    // 监听页面的真实跳转
    window.onpopstate = function(event) {
        alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
    };
</script>
</body>
</html>

通过上demo我们发现,HTML5 History API 可以修改浏览器URL地址,而并没有真实请求访问该地址的资源

而当我们使用回退或前进时,会按照正常的页面跳转逻辑更新url地址,并且还会触发 window.onpopstate 。

通过这两点我们大概可以猜出 React Router 的实现原理。

而当我们处于 HTML5 History API 修改的地址如 http://localhost:8080/abc ,此时如果刷新页面,浏览器会去请求该地址的资源。如果服务器资源不存在。当然会报错咯。


但 HTML5 History API 必须是支持 html5 的浏览器才可以使用,所以兼容性差强人意。所以有另一种更可靠的代替方案:

Hash 路由模式。此模式历史发展久远,而且相对成熟,不需要过多介绍,直接看例子即可:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button href="#user" style="cursor: pointer">进入user</button>
<button href="#news" style="cursor: pointer">进入news</button>
<script>
    window.onhashchange = function () {
        alert(window.location.hash)
    }
</script>
</body>
</html>

事实上,React Router 也支持 Hash 路由模式。只需要修改 BrowserRouter 为 HashRouter 即可:

// 修改前
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

// 修改后
import { HashRouter as Router, Route, Link } from 'react-router-dom'

我们惊奇的发现,在Hash模式下,刷新页面是可以继续预览的。而不会出现404界面。

当然这和锚点#是有关系的。所以我们通常建议使用Hash模式投入到生产环境中。

results matching ""

    No results matching ""