[react-router] hashHistory 和 browserHistory 的區別

react-router提供了三種方式來實現路由,並無默認的路由,須要在聲明路由的時候,顯式指定所使用的路由。html

//v1.x
<Router/>
//v2.0.0 // hash history import { hashHistory } from 'react-router' <Router history={hashHistory} />

  • browserHistory
  • hashHistory
  • createMemoryHistory

官方推薦使用browserHistoryreact

使用hashHistory,瀏覽器的url是這樣的:/#/user/liuna?_k=adseisnginx

使用browserHistory,瀏覽器的url是這樣的:/user/liunaexpress

這樣看起來固然是browerHistory更好一些,可是它須要server端支持。segmentfault

使用hashHistory時,由於有 # 的存在,瀏覽器不會發送request,react-router 本身根據 url 去 render 相應的模塊。瀏覽器

使用browserHistory時,從 / 到 /user/liuna, 瀏覽器會向server發送request,因此server要作特殊請求,好比用的 express 的話,你須要 handle 全部的路由 app.get('*', (req, res) => { ... }),使用了 nginx 的話,nginx也要作相應的配置。bash

 

若是隻是靜態頁面,就不須要用browserHistory,直接hashHistory就行了。微信

react router爲何推薦使用browserHistory而不推薦hashHistory?

首先 browserHistory 其實使用的是 HTML5 的 History API,瀏覽器提供相應的接口來修改瀏覽器的歷史記錄;而 hashHistory 是經過改變地址後面的 hash 來改變瀏覽器的歷史記錄;session

History API 提供了 pushState() 和 replaceState() 方法來增長或替換歷史記錄。而 hash 沒有相應的方法,因此並無替換歷史記錄的功能。但 react-router 經過 polyfill 實現了此功能,具體實現沒有看,好像是使用 sessionStorage。react-router

另外一個緣由是 hash 部分並不會被瀏覽器發送到服務端,也就是說無論是請求 http://domain.com/index.html#foo 仍是 http://domain.com/index.html#bar ,服務只知道請求了 index.html 並不知道 hash 部分的細節。而 History API 須要服務端支持,這樣服務端能獲取請求細節。

還有一個緣由是由於有些應該會忽略 URL 中的 hash 部分,記得以前將 URL 使用微信分享時會丟失 hash 部分。

相關文章
相關標籤/搜索