您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)vue-router路徑計(jì)算的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
起因
前端使用的是vue-router組件的history
模式,但是由于我們的整個(gè)頁(yè)面都是從static(靜態(tài)資源站)load過(guò)來(lái)的,所以其他頁(yè)面自然也需要跨域去拿,然而就在跨域的時(shí)候 vue-router 出了問(wèn)題。
分析問(wèn)題
我們的api站點(diǎn)在 api.com
而靜態(tài)資源在 static.com,頁(yè)面的base標(biāo)簽也指向static
<base href="http://static.com" rel="external nofollow" />
然而,在訪問(wèn) test
模板時(shí)卻跳到了http://api.com/http:/static.com/test
經(jīng)過(guò)一些簡(jiǎn)單的斷點(diǎn)調(diào)試,鎖定了以下代碼
[source]: https://github.com/vuejs/vue-router/blob/dev/dist/vue-router.esm.js
[vue-router.esm.js][source]
//1794行~1675行 function normalizeBase (base) { if (!base) { if (inBrowser) { // respect <base> tag var baseEl = document.querySelector('base'); base = (baseEl && baseEl.getAttribute('href')) || '/'; } else { base = '/'; } } // make sure there's the starting slash if (base.charAt(0) !== '/') { base = '/' + base; } // remove trailing slash return base.replace(/\/$/, '') }
這段代碼的作用是設(shè)置路由的base路徑,如果有興趣一路跟蹤的話會(huì)發(fā)現(xiàn)這個(gè)base
參數(shù)是由實(shí)例化VueRouter
時(shí)候傳入的options.base
;
再看代碼,他會(huì)判斷如果base是空的,那么就會(huì)給一個(gè)默認(rèn)值:
如果實(shí)在瀏覽器(非服務(wù)器環(huán)境)下執(zhí)行,那么會(huì)調(diào)用document.querySelector('base')
來(lái)嘗試獲取<base href='' />
標(biāo)簽中href
屬性的值;
在我們實(shí)際的場(chǎng)景中,這里得到一個(gè)跨域的絕對(duì)地址,然后緊接著
if (base.charAt(0) !== '/') { base = '/' + base; }
當(dāng)url第一個(gè)字符不是/
的時(shí)候加上/
,這里非常明顯是一個(gè)BUG
我的是絕對(duì)地址http://static.com
第一個(gè)字符當(dāng)然不是/
,所以才會(huì)由之前的http://api.com/http:/static.com/test
這樣的網(wǎng)址
修改
if(/^([a-z]+:)?\/\//i.test(base)){ }else if (base.charAt(0) !== '/') { base = '/' + base; }
為了盡量少破壞源碼,這里加了一個(gè)空的if,當(dāng)url是由協(xié)議開(kāi)始時(shí),認(rèn)為是絕對(duì)路徑。
* 絕對(duì)路徑還有一種形式是 //static.com
測(cè)試
經(jīng)過(guò)第一次修改,再次訪問(wèn)頁(yè)面依然有問(wèn)題,訪問(wèn)的頁(yè)面依然是http://api.com/http:/static.com/test
繼續(xù)分析
再次跟蹤源碼后發(fā)現(xiàn)
[vue-router.esm.js][source]
//2006行~2016行 HTML5History.prototype.push = function push (location, onComplete, onAbort) { var this$1 = this; var ref = this; var fromRoute = ref.current; this.transitionTo(location, function (route) { pushState(cleanPath(this$1.base + route.fullPath)); handleScroll(this$1.router, route, fromRoute, false); onComplete && onComplete(route); }, onAbort); }; //561行~563行 function cleanPath (path) { return path.replace(/\/\//g, '/') }
在發(fā)生pushState
之前,他還會(huì)對(duì)url再次進(jìn)行處理cleanPath
而這里的處理更簡(jiǎn)單,更粗暴,問(wèn)題也更大。
他直接將2個(gè)斜杠//
替換為1個(gè)斜杠/
,話說(shuō)如果連續(xù)3個(gè)斜杠怎么辦?
所以在處理http://static.com/test
地址的時(shí)候,其實(shí)會(huì)被處理成http:/static.com/test
又變成相對(duì)路徑了...
繼續(xù)修改
function cleanPath (path) { var ishttp = /^([a-z]+:)?\/\//i.exec(path); var http = Array.isArray(ishttp) ? ishttp[0] : ''; return http + path.substr(http.length).replace(/\/{2,}/g, '/'); }
如果是協(xié)議開(kāi)始,則排除協(xié)議內(nèi)容之后,將2個(gè)或2個(gè)以上連續(xù)在一起的斜杠替換為1個(gè)斜杠。
** 完成提交pull
感謝各位的閱讀!關(guān)于“vue-router路徑計(jì)算的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。