--- tags: Javascript --- # 實作瀏覽器 URL WebAPIs 還在學習中,記錄一下在工作上遇到的問題 **需求** * 在頁面中實踐 SPA * 新增自訂義 query string,放到為 URL 中 * 頁面可以依據 query string 的內容去發 API --- ## 實作步驟: 瀏覽本身提供了 URL、URLSearchParams 的 WebAPIs 可以使用 參考:[URL](https://developer.mozilla.org/zh-CN/docs/Web/API/URL)、[URLSearchParams](https://developer.mozilla.org/zh-CN/docs/Web/API/URLSearchParams) ### 1. 拿取當前頁面的 URL,加入 query string ```javascript= const currentUrl = new URL(window.location.href); const searchParams = new URLSearchParams(); searchParams.append('item', 100); currentUrl.search = searchParams; const address = `http://www.test.com/page${currentUrl.search}`; console.log(address); // http://www.test.com/page?item=100 ``` URLSearchParams 還有提供很多方法可以對參數/值做事: ```javascript URLSearchParams.append() // 插入一個自定義的參數與值 URLSearchParams.delete() // 刪除指定參數及值 URLSearchParams.get() // 取得指定查詢的參數(第一個值) URLSearchParams.has() // 判斷參數是否存在 ``` ### 2. 將自定義的 URL 加入到瀏覽器的歷史紀錄堆疊(history stack) HTML5 提供了可以儲存網頁歷史紀錄的方法: `history.pushState()` 和 `history.replaceState()` 方法 兩者差別在紀錄堆疊的方式不同,細節可參考:[History API](https://developer.mozilla.org/zh-TW/docs/Web/API/History_API#%E5%9C%A8%E6%AD%B7%E5%8F%B2%E7%B4%80%E9%8C%84%E4%B8%AD%E7%A7%BB%E5%8B%95) **state**:可儲存一個 state 物件,並能在 onpopstate 事件中拿到該值 **title**:更新後頁面的標題,目前瀏覽器會忽略,文件中建議給空字串 **url**:設定要更新歷史紀錄的 URL ```javascript! // history.pushState(state, title, url); history.pushState(null, null, address); ``` --- ## 遇到問題 被更換過的 URL 頁面,若點擊瀏覽器的上一頁按鈕卻沒有反應,但 URL 確實有被置換,查詢文件後發現,<font color="red">**瀏覽器對於新的URL並不會重新加載、檢查存在與否**</font> ![](https://i.imgur.com/FlixwfO.png) ## 解決方式 使用瀏覽器提供的方法 `window.onpopstate` [Window.onpopstate](https://developer.mozilla.org/zh-TW/docs/Web/API/Window/popstate_event) 該方法會在會在歷史紀錄有發生變動時被觸發(例如點擊瀏覽器的上下一頁按鈕)一個 popstate event 我們就可以在事件中,加入自定義的內容,去判斷當前狀態是否需要進行頁面重載 ```javascript! window.onpopstate = function(event) { if (event.state) return location.reload(); } ``` ![](https://i.imgur.com/IwbZgfR.png) ## 參考相關資料 * [操控瀏覽器歷史紀錄](https://developer.mozilla.org/zh-TW/docs/Web/API/History_API#%E5%9C%A8%E6%AD%B7%E5%8F%B2%E7%B4%80%E9%8C%84%E4%B8%AD%E7%A7%BB%E5%8B%95) * [瀏覽器的時光機—歷史堆疊、 pushState 與 replaceState API](https://medium.com/%E5%89%8D%E7%AB%AF%E5%AF%A6%E5%8A%9B%E4%B8%89%E6%98%8E%E6%B2%BB/%E7%80%8F%E8%A6%BD%E5%99%A8%E7%9A%84%E6%99%82%E5%85%89%E6%A9%9F-pushstate-replacestate-api-fa1d909c82b0) * [history.pushState - not working?](https://stackoverflow.com/questions/14824766/history-pushstate-not-working)