《前端實戰總結》如何在不刷新頁面的狀況下改變URL

因爲公司最近有個需求是想讓咱們的get請求的參數都直接顯示在瀏覽器url上,這樣咱們就能夠直接經過複製url來顯示對應的界面數據了。javascript

背景介紹

因爲咱們經常使用的http請求通常是基於XHR對象的實現或者fetch實現,這種請求操做並不會觸發瀏覽器url的變化,這樣雖然也能正常請求數據並渲染到頁面,可是若是用戶在當前頁面操做了某個get請求並獲得了某條數據,想經過連接將當前看到的界面分享給其餘人時,那麼此時瀏覽器url並不會變化,經過連接只能訪問到初始化的數據界面,此時並不能達到理想的效果。以下圖所示:css

(單純使用ajax或者fetch實現get請求時)
當咱們在該頁面將列表切換到第二頁時,瀏覽器url並無變化,因此將連接複製給其餘人打開並不會將列表結果切換到第二頁,而是從新初始化。

實現過程

經過以上的背景和問題,咱們能夠想一想能夠怎麼實現呢?個人第一個反應就是使用location API來實現,咱們可使用location.search來讀寫瀏覽器query參數:前端

location.search = '?page=2';
複製代碼

這段代碼雖然能夠改變瀏覽器url,以下圖所示:vue

但會出現一個性能問題,就是當咱們執行了以上代碼後,整個瀏覽器都會刷新,致使咱們不想刷新的部分也刷新了,那咱們有辦法可讓它局部刷新嗎? 答案是必須有。

這裏就要引出咱們本文的重點:history APIjava

history API

Window.history是一個只讀屬性,用來獲取History 對象的引用,History 對象提供了操做瀏覽器會話歷史(瀏覽器地址欄中訪問的頁面,以及當前頁面中經過框架加載的頁面)的接口。HTML5引入了 history.pushState() 和 history.replaceState() 方法,它們分別能夠添加和修改歷史記錄條目。node

使用 history.pushState() 能夠改變referrer,它在用戶發送 XMLHttpRequest 請求時在HTTP頭部使用,改變state後建立的 XMLHttpRequest 對象的referrer都會被改變。由於referrer是標識建立 XMLHttpRequest 對象時 this 所表明的window對象中document的URL。webpack

那麼咱們就可使用pushState來實現咱們的更新瀏覽器url功能了。css3

pushState() 方法

pushState() 須要三個參數: 一個狀態對象, 一個標題 (目前已忽略), 和 (可選的) 一個URL:es6

  • 狀態對象 — 狀態對象state是一個JavaScript對象,經過pushState () 建立新的歷史記錄條目。不管何時用戶導航到新的狀態,popstate事件就會被觸發,且該事件的state屬性包含該歷史記錄條目狀態對象的副本
  • 標題 — Firefox 目前忽略這個參數,但將來可能會用到。在此處傳一個空字符串應該能夠安全的防範將來這個方法的更改。或者,你能夠爲跳轉的state傳遞一個短標題
  • URL — 該參數定義了新的歷史URL記錄。注意,調用 pushState() 後瀏覽器並不會當即加載這個URL,但可能會在稍後某些狀況下加載這個URL,好比在用戶從新打開瀏覽器時。新URL沒必要須爲絕對路徑。若是新URL是相對路徑,那麼它將被做爲相對於當前URL處理。新URL必須與當前URL同源,不然 pushState() 會拋出一個異常。該參數是可選的,缺省爲當前URL

實現

/** * 設置瀏覽器url * params:queryObj(參數對象) */
function setBrowserUrl(queryObj){
    // stringify是queryString的一個api,具體能夠查看node官網,也能夠本身實現
    var url = `${location.pathname}?${stringify(queryObj)}`
    history.pushState({url: url}, '', url)
}
複製代碼

這樣咱們就能夠在請求的同時,調用setBrowserUrl方法來改變瀏覽器url了。 接下來咱們就能夠監聽瀏覽器url的變化,若是瀏覽器url有須要的請求參數,那麼咱們就根據請求參數來請求數據,沒有就初始化頁面,這樣當咱們查看某條記錄或者某個小祕密時,想把該數據保存下來並分享給被人,是否是就能夠實現了呢?web

總結

基於H5 history能夠實現不少優雅使用的工具,好比路由,緩存控件等等。 若是想了解更多webpack,gulp,css3,javascript,nodeJS,canvas等前端知識和實戰,歡迎在公衆號《趣談前端》加入咱們一塊兒學習討論,共同探索前端的邊界。

更多推薦

相關文章
相關標籤/搜索