僅個人理解,如有不當請指正
一、從原理上
HashRouter在路徑中包含了#,相當於HTML的錨點定位。(#
符號的英文叫hash,所以叫HashRouter,和散列沒關系哦))
而BrowserRouter使用的是HTML5的新特性History,沒有HashRouter(錨點定位)那樣通用,低版本瀏覽器可能不支持。
二、從用法上
BrowserRouter進行組件跳轉時可以傳遞任意參數實現組件間的通信,而HashRouter不能(除非手動拼接URL字符串),因此一般配合Redux使用,實現組件間的數據通信。
三、生產實踐
1.HashRouter
HashRouter相當於錨點定位,因此不論#后面的路徑怎么變化,請求的都相當於是#之前的那個頁面。可以很容易的進行前后端不分離的部署(也就是把前端打包后的文件放到服務器端的public或static里),
因為請求的鏈接都是ip地址:端口/#/xxxx,因此請求的資源路徑永遠為/,相當於index.html,而其他的后端API接口都可以正常請求,不會和/沖突,由於前后端不分離也不會產生跨域問題。
缺點就是丑,路徑里總有個#,寶寶表示強迫症犯了...
2.BrowserRouter
因為BrowserRouter模式下請求的鏈接都是ip地址:端口/xxxx/xxxx,因此相當於每個URL都會訪問一個不同的后端地址,如果后端沒有覆蓋到路由就會產生404錯誤。
可以通過加入中間件解決,放在服務器端路由匹配的最后,如果前面的API接口都不匹配,則返回index.html頁面。但這樣也有一些小問題,因為要求前端路由和后端路由的URL不能重復。
比如商品列表組件叫/product/list,而請求商品列表的API也是/product/list,那么就會訪問不到頁面,而是被API接口匹配到。
解決方法:
進行前后端分離的部署,比如前端地址ip1:端口1,后端接口地址ip2:端口2,使用Nginx反向代理服務器進行請求分發。前端向后端發起請求的URL為nginx所在的服務器+/api/xxx,通過NGINX的配置文件判斷,如果URL以api開頭則轉發至后端接口,否則轉發至前端的地址,訪問項目只需訪問Nginx服務器即可。