碎碎念:之前用react-router的時候直接用的舊項目默認配置,沒有仔細去了解爲什麼url上面會自帶#,趁着週末查閱了一下資料,自己總結一下。
一、理解什麼是react-router history
直接拿開發文檔裏的原話:
React Router 是建立在 history 之上的。 簡而言之,一個 history 知道如何去監聽瀏覽器地址欄的變化, 並解析這個 URL 轉化爲
location
對象, 然後 router 使用它匹配到路由,最後正確地渲染對應的組件。
history分爲三種: browserHistory / hashHistory / createMemoryHistory
其中browserHistory / hashHistory 兩種常用於前端路由。那麼兩者最顯著的區別就是:
使用hashHistory作爲路由,url上會自帶參數 # ,形如 192.168.0.1:3000/#/main
而 browserHistory 則是:192.168.0.1:3000/main
原因:
1. 兩者對路由路徑處理的方式不一樣,hashHistory是對#後面的路徑進行處理,由前端通過html history(使用這種路由,可以在控制檯打印出當前路由history的情況(console.log(this.props.history)))進行管理。而browserHistory則需要通過服務端的配置 前端纔可以正確拿到返回。
2.那麼爲什麼browserHistory需要服務端配置纔可以呢?
Browser history 是使用 React Router 的應用推薦的 history。它使用瀏覽器中的 History API 用於處理 URL,創建一個像
example.com/some/path
這樣真實的 URL
browserHistory訪問後臺接口的時候後臺收到的是形如 “/mian/index” 的形式,如果後臺沒有做映射,那麼後臺的所有資源都是存放在 “/” 下的,這個時候就拿不到數據。但如果是第一次進入主頁面,發送的請求是 “/” 形式的話,就拿得到數據,如果是進入其他頁面,或者來回跳轉,url產生了變化,發送的請求變成了“/main/index” 之類的話,就是我上面說的情況了。所以服務端必須要做相應的資源路徑映射。
再看hashHistory,真實URL其實是指向服務器資源,比如我們經常使用的API接口,也是一個真實URL的資源路徑,當通過真實URL訪問網站的時候,通過hashHistory來生成的URL就不會出現這樣的問題,因爲他不是指向真實的路由。hashHistory的路徑是從#開始的,它的所有處理是在前端完成,可以打開控制檯看一下請求列表裏,發送出去的請求api是不帶#的,就是說前端已經處理過url發送給後臺。(我是這麼理解的,不知道是否準確,如果有誤大神可以幫忙糾正一下哈~)
二、配置服務端路徑
看了很多文章都是直接copy開發文檔的代碼,這裏直接指路文檔地址:
http://react-guide.github.io/react-router-cn/docs/guides/basics/Histories.html#creatememoryhistory
三、history屬性詳解
常見字段:
length: number 瀏覽歷史堆棧中的條目數
action: string 路由跳轉到當前頁面執行的動作,分爲 PUSH, REPLACE, POP
location: object 當前訪問地址信息組成的對象,具有如下屬性:
pathname: string URL路徑
search: string URL中的查詢字符串
hash: string URL的 hash 片段
state: string 例如執行 push(path, state) 操作時,location 的 state 將被提供到堆棧信息裏,state 只有在 browser 和 memory history 有效。
push(path, [state]) 在歷史堆棧信息里加入一個新條目。
replace(path, [state]) 在歷史堆棧信息裏替換掉當前的條目
go(n) 將 history 堆棧中的指針向前移動 n。
goBack() 等同於 go(-1) eg. this.props.history.goBack() 等於瀏覽器左上角的回退
goForward 等同於 go(1)
block(prompt) 阻止跳轉
history 對象是可變的,因爲建議從 <Route> 的 prop 裏來獲取 location,而不是從 history.location 直接獲取
四、react路由配置示例
import React from 'react'
import {HashRouter as Router, Redirect, Route, Switch} from 'react-router-dom';
import App from '../components/App'
import Home from '../components/Home'
import About from '../components/About'
import Features from '../components/Features'
render(
<Router>
<Switch>
<Route path={'/app'} component={App}/>
<Route path={'/home'} component={Home} />
<Route path={'/About'} component={About} />
<Route path={'/features/:id'} component={Features}/>
<Route path="*" component={Home}/>
</Switch>
</Router>,
document.getElementById('app')
)
參考文檔:
http://react-guide.github.io/react-router-cn/docs/guides/basics/Histories.html
https://blog.csdn.net/qq_29854831/article/details/79636095
https://blog.csdn.net/oqqmihu123/article/details/59529481