不同类型的history间还是存在差异的,这需要你去考虑选择一个适合你项目的history。
Between the three of them, any use case should be covered.
browser history与hash history都被用于浏览器环境。它们与history和location的web API进行交互,因此当前location与浏览器地址栏中展示的是相同的。
const browserHistory = createBrowserHistory() const hashHistory = createHashHistory()
它们两者的最大区别在于从URL创建location的方式。browser history使用完整URL[注3],而hash history只使用在第一个hash后的那部分URL。
// 提供如下URL url = 'http://www.example.com/this/is/the/path?key=value#hash' // browser history创建的location对象: { pathname: '/this/is/the/path', search: '?key=value', hash: '#hash' } //hash history创建的location对象: { pathname: 'hash', search: '', hash: '' }
使用哈希为何你需要hash history?理论上来说当你导航到一个URL时,服务端必有一个相应文件与之对应。对于动态服务,请求文件并不需要真实存在。相反,服务端会检查请求的URL并决定返回的HTML。
然而,静态文件服务可以直接返回存在磁盘中的文件。静态服务能做的最动态的事就是当URL制定目录时,从目录中返回index.html文件。
由于静态文件服务的这种限制,最简单的解决方案[注4]就是在服务端仅使用一个真实的location来返回用户端的获取需求。当然,仅有一个location意味着你的应用只有一个URL,这样就无法使用history。为了解决这一问题,hash history使用使用URL的哈希部分来读写location。
// 如果 example.com 使用静态资源服务, 这三个URL都将从 // /my-site/index.html获取相同数据 #/one #/two // 然而由于使用hash history,应用中三者的location是不同的, // 因为location取决于URL的哈希部分 { pathname: '/one' } { pathname: '/two' }
纵然hash history运作良好,但由于其依赖将所有路径信息存在URL的哈希中,它被认为有可能遭到黑客攻击。因此当网站没有动态服务时再考虑使用它吧。
memory:缓存所有history使用memory location最棒的体验就是你可以在能使用JavaScript的地方随意使用。
一个简单的例子你可以通过运行Node在单元测试中使用它。这允许你能在不依赖浏览器运行的情况下测试代码。
更牛逼的是,memory history可以被使用在app中。在react-nativeapp中react-router-native使用memory history来实现基于location的导航。
你可以在浏览器中使用使用memory history,如果你愿意的话。(虽然这样你会失去与地址栏的交互能力)。
这memory history与其他两类history最大的区别在于其维护着自己的location。当创建memory history后你可以传入信息进行初始化状态。这个状态是一个location数组与当前location的索引[注5]。这与其他两类history是不同的,它们依赖浏览器来存储这个location数组。
const history = createMemoryHistory({ initialEntries: ['https://www.jb51.net/', '/next', '/last'], initialIndex: 0 })
使用history代替你来处理哪些相对繁琐且易错的是一个行之有效的方法。
无论你选择了何种类型的history,他们都是极易使用,并且拥有强大的能力进行导航与基于loaction的渲染。
注释[1] search属性是一个字符串而非被解析对象。由于大多数字符串解析包在使用上各不相同。所以history把选择权留给了开发者而不是强制使用某种字符串解析包。如果你想了解更多,这里推荐一些流行的:query-string,querystring与原生的URLSearchParams
[2] 这是出于安全性的限制。在浏览器中history的location数组不仅包涵了访问过的location信息。如果开放浏览会泄漏使用者的浏览器历史信息,因此无法开放访问。
[3] m默认情况下,browser history创建的location对象,它的路径名是URL全路径名。当然,你可以为history定一个基础名,这样路径名中的这部分将会被忽略。
const history = createBrowserHistory({ basename: '/path' }) // 给出的路径 url: // history对象将会创建如下location { pathname: '/here', ... }