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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

容易忽略的URL

發(fā)布時(shí)間:2023/12/31 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 容易忽略的URL 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

場景再現(xiàn)

眾所周知,vue-router有三種模式 :hash、html5、abstract , 一般的前端項(xiàng)目中會(huì)選擇hash模式進(jìn)行開發(fā),最近做了一個(gè)運(yùn)營活動(dòng)就是基于vue-router的hash模式進(jìn)行開發(fā)的。

  • 項(xiàng)目注冊(cè)了兩個(gè)路由(抽象出來的Demo)
var router = new VueRouter({routes: [{name: 'index',path: '',component: indexcomponent},{name: 'demo',path: '/demo',component: democomponent}] });
  • 入口頁面需要參數(shù),所以提供URL:https://www.xxx.com?from=weixin, 瀏覽器里輸入U(xiǎn)RL回車后,頁面自動(dòng)增加一個(gè)#/變?yōu)閔ttps://www.xxx.com?from=weixin#/。
  • index頁面中一個(gè)按鈕點(diǎn)擊后跳轉(zhuǎn)demo,同時(shí)想攜帶index中獲取的參數(shù),看API選擇了如下方式,結(jié)果URL變成了:https://www.xxx.com?from=weixin#/test?userId=123
router.push({ path: 'demo',query: { plan: 'private'} })

產(chǎn)生質(zhì)疑

  • URL有什么標(biāo)準(zhǔn)?(上面Demo頁面跳轉(zhuǎn)后URL看起來怪怪的)
  • vue-router是如何控制URL的?

質(zhì)疑探究

URL標(biāo)準(zhǔn)

統(tǒng)一資源定位符(或稱統(tǒng)一資源定位器/定位地址、URL地址等,英語:Uniform Resource Locator,常縮寫為URL)

標(biāo)準(zhǔn)格式:scheme:[//authority]path[?query][#fragment]

==例子==

下圖展示了兩個(gè) URI 例子及它們的組成部分。<!-- 基于 RFC 3986 中的例子格式 -->
<pre style="font-family:Courier,Courier New,DejaVu Sans Mono;monospace">

hierarchical part┌───────────────────┴─────────────────────┐authority path┌───────────────┴───────────────┐┌───┴────┐

abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
└┬┘ └───────┬───────┘ └────┬────┘ └┬┘ └─────────┬─────────┘ └──┬──┘
scheme user information host port query fragment

urn:example:mammal:monotreme:echidna
└┬┘ └──────────────┬───────────────┘
scheme path</pre>

URL中的『?』『#』

  • 『?』

    • 路徑與參數(shù)分隔符
    • 瀏覽器只識(shí)別url中的第一個(gè)『?』,后面的會(huì)當(dāng)做參數(shù)處理
  • 『#』

    • 『#』一般是頁面內(nèi)定位用的,如我們最熟悉不過的錨點(diǎn)定位
    • 瀏覽器可以通過『onhashchange』監(jiān)聽hash的變化
    • http請(qǐng)求中不包含#
    • Request Headers中的Referer不包含#
    • 改變#不觸發(fā)網(wǎng)頁重載
    • url中#后面出現(xiàn)的任何字符都會(huì)被截?cái)唷?#xff08;http://www.xxx.com/?color=#fff發(fā)出請(qǐng)求是:/color=)
    • 改變#會(huì)改變history
    • window.location.hash讀取#值

URL讀取和操作

URL讀取和操作涉及l(fā)ocation和history兩個(gè)對(duì)象,具體如下:

location API :

  • 屬性

    • href = protocol + hostName + port + pathname + search + hash
    • host
    • origin
  • 方法

    • assign
    • href
    • replace ,不記錄history
    • reload

history API:

  • 方法

    • back()
    • forward()
    • go()
  • H5新增API

    • pushState()
    • replaceState()
    • popstate監(jiān)聽變化

vue-router路由實(shí)現(xiàn)淺析

初始化router的時(shí)候,根據(jù)指定的mode選擇路由實(shí)現(xiàn),當(dāng)然mode判斷有一定邏輯和兼容策略

switch (mode) {case 'history':this.history = new HTML5History(this, options.base)breakcase 'hash':this.history = new HashHistory(this, options.base, this.fallback)breakcase 'abstract':this.history = new AbstractHistory(this, options.base)breakdefault:if (process.env.NODE_ENV !== 'production') {assert(false, `invalid mode: ${mode}`)} }

我們選擇hash模式進(jìn)行深入分析,對(duì)應(yīng)HashHistory模塊,該模塊是history/hash.js實(shí)現(xiàn)的,當(dāng)被調(diào)用的時(shí)候,對(duì)全局路由變化進(jìn)行了監(jiān)聽

window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', () => {... })

同時(shí)hash.js中也實(shí)現(xiàn)了push等api方法的封裝,我們以push為例,根據(jù)源碼可以看出,它的實(shí)現(xiàn)是基于基類transitionTo的實(shí)現(xiàn),具體如下:

push (location: RawLocation, onComplete?: Function, onAbort?: Function) {const { current: fromRoute } = thisthis.transitionTo(location, route => {pushHash(route.fullPath)handleScroll(this.router, route, fromRoute, false)onComplete && onComplete(route)}, onAbort)}

既然調(diào)用了transitionTo那么來看它的實(shí)現(xiàn),獲取參數(shù)后調(diào)用confirmTransition

transitionTo (location: RawLocation, onComplete?: Function, onAbort?: Function) {// 獲取URL中的參數(shù)const route = this.router.match(location, this.current)this.confirmTransition(route, () => {this.updateRoute(route)onComplete && onComplete(route)this.ensureURL()...})}

同時(shí)confirmTransition里實(shí)現(xiàn)了一個(gè)隊(duì)列,順序執(zhí)行,iterator通過后執(zhí)行next,進(jìn)而志新pushHash(),實(shí)現(xiàn)頁面hash改變,最終實(shí)現(xiàn)了${base}#${path}的連接

function getUrl (path) {const href = window.location.hrefconst i = href.indexOf('#')const base = i >= 0 ? href.slice(0, i) : hrefreturn `${base}#${path}` }function pushHash (path) {if (supportsPushState) {pushState(getUrl(path))} else {window.location.hash = path} }

問題解決

  • https://www.xxx.com?from=weixin#/test?userId=123這個(gè)頁面看起來感覺怪,是因?yàn)檫@個(gè)連接中幾乎包含了所有的參數(shù),而且hash里面還有一個(gè)問號(hào),一個(gè)URL中多個(gè)問號(hào)的不常見
  • vue-router也是基于基本的URL操作來進(jìn)行URL切換的,在基本基礎(chǔ)上進(jìn)行了封裝。里面很多思路還是應(yīng)該多學(xué)習(xí)借鑒的。比如實(shí)現(xiàn)的隊(duì)列、繼承的運(yùn)用等

總結(jié)

  • 標(biāo)準(zhǔn)的URL應(yīng)該是 search + hash ,不要被當(dāng)下各種框架欺騙,誤以參數(shù)應(yīng)該在hash后面拼接
  • URL中可以有多個(gè)問號(hào),但為了便于理解,還是盡量避免這種寫法
  • 避免上面尷尬問題的一個(gè)方法是 HTML5 Histroy 模式,感興趣的同學(xué)可以關(guān)注并實(shí)踐一下
  • 了解原理,了解設(shè)計(jì)模式,可以借鑒到平時(shí)開發(fā)項(xiàng)目中

參考文檔

  • https://github.com/vuejs/vue-...
  • https://developer.mozilla.org...
  • https://en.wikipedia.org/wiki...
  • https://www.cnblogs.com/qingg...
  • http://www.cnblogs.com/qinggu...
  • https://segmentfault.com/p/12...
  • https://segmentfault.com/a/11...

總結(jié)

以上是生活随笔為你收集整理的容易忽略的URL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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