日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript hash 与 history 实现客户端路由的原理

發(fā)布時(shí)間:2023/12/16 javascript 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript hash 与 history 实现客户端路由的原理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

客戶端路由有兩種實(shí)現(xiàn)方式:基于hash 和基于html5 history api。
vue-router 組件就是基于它們來實(shí)現(xiàn)的。

vue-router 組件中的路由涉及到了三個(gè)基本的概念: route, routes, router。

  • route,它是一條路由,由這個(gè)英文單詞也可以看出來,它是單數(shù), Home按鈕 => home內(nèi)容, 這是一條route, about按鈕 => about 內(nèi)容, 這是另一條路由。
  • routes 是一組路由,把上面的每一條路由組合起來,形成一個(gè)數(shù)組。[{home 按鈕 =>home內(nèi)容 }, { about按鈕 => about 內(nèi)容}]
  • router 是一個(gè)機(jī)制,相當(dāng)于一個(gè)管理者,它來管理路由。因?yàn)閞outes 只是定義了一組路由,它放在哪里是靜止的,當(dāng)真正來了請求,怎么辦? 就是當(dāng)用戶點(diǎn)擊home 按鈕的時(shí)候,怎么辦?這時(shí)router 就起作用了,它到routes 中去查找,去找到對應(yīng)的 home 內(nèi)容,所以頁面中就顯示了 home 內(nèi)容。
  • 客戶端中的路由,實(shí)際上就是dom 元素的顯示和隱藏。VUE會將頁面中所有內(nèi)容全部組件化的,根據(jù)當(dāng)前路由分別做顯示或隱藏。例如:當(dāng)頁面中顯示home 內(nèi)容的時(shí)候,about 中的內(nèi)容全部隱藏,反之也是一樣。
  • 回到 H5 的 history 上來。

    history 可以通過參數(shù)來保存用戶的操作,并且無需刷新就可以在頁面間進(jìn)行切換。常見于單頁面應(yīng)用(SPA,Simple Page Application)框架里。

    window.history 對象在編寫時(shí)可不使用 window 這個(gè)前綴。

    • history.back()
      加載歷史列表中的上一個(gè) URL,與瀏覽器點(diǎn)擊后退按鈕作用相同。等價(jià)于history.go(-1)。
      返回上一頁時(shí),頁面通常是從瀏覽器緩存之中加載,而不是重新要求服務(wù)器發(fā)送新的網(wǎng)頁。
    • history.forward()
      加載歷史列表中的下一個(gè) URL,與瀏覽器點(diǎn)擊向前按鈕作用相同。等價(jià)于history.go(-1)。
    • history.go(int n)
      移動到該整數(shù)指定的頁面,比如go(1)相當(dāng)于forward(),go(-1)相當(dāng)于back(),history.go(0)相當(dāng)于刷新當(dāng)前頁面。

    如果移動的位置超出了訪問歷史的邊界,以上三個(gè)方法并不報(bào)錯(cuò),而是默默的失敗。

    • history.scrollRestoration
      設(shè)置滾動恢復(fù)行為。通俗的來講就是,當(dāng)我們從當(dāng)前頁面跳轉(zhuǎn)到a頁面,隨后又從a頁面回退過來的時(shí)候,我們的頁面是否應(yīng)該自動滾動到我們之前瀏覽的位置。
      scrollRestoration默認(rèn)值是auto,默認(rèn)滾動恢復(fù)。另外一個(gè)值是manual,表示不會默認(rèn)恢復(fù)

    • window.location
      對象用于獲得當(dāng)前頁面的地址 (URL),或?qū)g覽器重定向到新的頁面。

      • location.hash 設(shè)置或返回從井號 (#) 開始的 URL(錨)
      • location.host 設(shè)置或返回主機(jī)名和當(dāng)前 URL 的端口號
      • location.hostname 設(shè)置或返回當(dāng)前 URL 的主機(jī)名
      • location.href 屬性返回當(dāng)前頁面的 URL
      • location.pathname 設(shè)置或返回當(dāng)前 URL 的路徑部分
      • location.port 設(shè)置或返回當(dāng)前 URL 的端口號
      • location.protocol 設(shè)置或返回當(dāng)前 URL 的協(xié)議(http:// 或 https://)
      • search 設(shè)置或返回從問號 (?) 開始的 URL(查詢部分)
      • location.assign(url) 加載新的文檔
      • location.reload() 重新加載當(dāng)前文檔
      • location.replace(url) 加載新的文檔,在歷史列表中,新文檔會替換當(dāng)前文檔

    HTML5為history對象添加了兩個(gè)新方法,history.pushState()和history.replaceState(),用來在瀏覽歷史中添加和修改記錄。

    • history.pushState(state, title, url)
      調(diào)用該方法后,瀏覽器只會替換地址欄地址,并且推入歷史列表,但并不會刷新頁面。
      • state 存儲數(shù)據(jù)的對象,瀏覽器會自動序列化。最大存儲空間為640k,超過這個(gè)值會拋出錯(cuò)誤。當(dāng)瀏覽器地址改變,且處于同一域的時(shí)候,會觸發(fā)popstate事件,該事件的參數(shù)event.state即為本對象。
      • title 設(shè)置標(biāo)題(所有瀏覽器均不支持)
      • url 地址欄替換成新的URL(在firefox下測試發(fā)現(xiàn),url只支持相對地址,且必須在該域名下面;如果原地址已html結(jié)尾,那么只能加#)

    在本地測試的時(shí)候,大家可能會遇到如下問題:SecurityError: The operation is insecure.
    ?
    https://stackoverflow.com/questions/13348766/securityerror-the-operation-is-insecure-window-history-pushstate
    ?
    Make sure you are following the Same Origin Policy. This means same domain, same subdomain, same protocol (http vs https) and same port.
    ?
    How does pushState protect against potential content forgeries?
    ?
    As @robertc aptly pointed out in his comment, some browsers actually implement slightly different security policies when the origin is file:///. Not to mention you can encounter problems when testing locally with file:/// when the page expects it is running from a different origin (and so your pushState assumes production origin scenarios, not localhost scenarios)
    ?
    翻譯如下:
    請確認(rèn)你遵守了同源策略。它意味著相同的域名,相同的子域名,相同的協(xié)議(http 和 https)和端口。
    那么 pushState 如何防止?jié)撛诘膬?nèi)容偽造呢?
    正如某人在他的評論中指出的,一些瀏覽器對于源是 file:/// 的實(shí)現(xiàn)稍有不同。這并不意味著當(dāng)你在本地測試 來自不同源的 file:/// 的時(shí)候會遭遇困難(因此你可以在生產(chǎn)腳本上測試pushState,而非本地腳本)

    最佳回答說了一堆廢話。簡而言之就是 pushState只適用于http 和 https協(xié)議,而對于 file 協(xié)議僅能采用錨點(diǎn),其他都違反了安全策略

    • history.replaceState(state, title, url)
      replaceState和pushState的參數(shù)一摸一樣,功能也差不多。
      唯一的區(qū)別是:pushState()是在history棧中添加一個(gè)新的條目,replaceState()是替換當(dāng)前的記錄值。

    • window.addEventListener(“popstate”, (event)=>{})
      history 實(shí)體改變時(shí)觸發(fā)的事件。通過在popstate()事件中添加pushState()方法,可以讓用戶無法后退,且頁面不會刷新

    測試代碼如下

    <!DOCTYPE html> <html> <head> <meta charset="utf8"> <script> function objToStr(obj) {let desc = ""; for(let i in obj){ let property = obj[i]; desc += i + " = " + property + "<br>"; }return desc; } function init() {document.getElementById("number").value = -1;const locationElem = document.getElementById("location");locationElem.innerHTML = "location: <br>" + objToStr(location);const historyElem = document.getElementById("history");historyElem.innerHTML = "history: <br>" + objToStr(history);window.addEventListener("popstate", (event)=>{console.log(event);//通過在popstate添加pushState方法,可以讓用戶無法后退,且頁面不會刷新//pushState();}, false); } function pushState() {var state = {title: "title",url: "#history"};window.history.pushState(state, state.title, state.url); } </script> </head> <body "init()"> <button onclick="javascript:history.forward()">forward</button> <button onclick="javascript:history.back()">back</button> <div> <input type="number" id="number"/><button onclick="javascript:history.go(document.getElementById('number').value)">go</button> </div> <!-- history: go = function go() { [native code] } back = function back() { [native code] } forward = function forward() { [native code] } pushState = function pushState() { [native code] } replaceState = function replaceState() { [native code] } length = 3 scrollRestoration = auto state = null --> <p id="history"></p><button onclick="javascript:location='http://www.baidu.com'">relocate</button> <!-- location: href = file:///D:/node/test20181018/public/history.html origin = null protocol = file: host = hostname = port = pathname = /D:/node/test20181018/public/history.html search = hash = assign = function assign() { [native code] } replace = function replace() { [native code] } reload = function reload() { [native code] } toString = function toString() { [native code] } --> <p id="location"></p> <button onclick="pushState()">pushState</button> </body> </html>

    總結(jié)

    以上是生活随笔為你收集整理的JavaScript hash 与 history 实现客户端路由的原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。