關(guān)于vue-router路徑計(jì)算問(wèn)題
昨天剛剛發(fā)表了一個(gè)前端跨域新方案嘗試,今天在開發(fā)中就遇到的了問(wèn)題。
起因
前端使用的是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 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é)議開始時(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é)議開始,則排除協(xié)議內(nèi)容之后,將2個(gè)或2個(gè)以上連續(xù)在一起的斜杠替換為1個(gè)斜杠。
** 完成提交pull
https://github.com/vuejs/vue-router/pull/1353/files
話說(shuō)vue-router的url處理比起Url.js來(lái)說(shuō)真的是太粗暴了...
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue-cli打包后本地運(yùn)行dist文件中的index.html操作
這篇文章主要介紹了vue-cli打包后本地運(yùn)行dist文件中的index.html操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
vite打包優(yōu)化CDN壓縮的分析實(shí)現(xiàn)
我們?cè)谌粘5墓ぷ髦锌隙〞?huì)遇到項(xiàng)目打包優(yōu)化等問(wèn)題,本文主要介紹了vite打包優(yōu)化CDN壓縮的分析實(shí)現(xiàn),具有一定的參加價(jià)值,感興趣的可以了解一下2024-07-07
Vue實(shí)現(xiàn)星級(jí)評(píng)價(jià)效果實(shí)例詳解
這篇文章主要介紹了Vue實(shí)現(xiàn)星級(jí)評(píng)價(jià)效果的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Vue數(shù)據(jù)驅(qū)動(dòng)模擬實(shí)現(xiàn)4
這篇文章主要介紹了Vue數(shù)據(jù)驅(qū)動(dòng)模擬實(shí)現(xiàn)的相關(guān)資料,介紹了Array的變異方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
解決Electron?store的commit和dispatch不好用問(wèn)題
這篇文章主要介紹了解決Electron?store的commit和dispatch不好用問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
vue中通過(guò)iframe方式加載本地的vue頁(yè)面的解決方法
這篇文章主要給大家介紹了在vue中如何通過(guò)iframe方式加載本地的vue頁(yè)面的解決方法,文中有詳細(xì)的解決流程,需要的朋友可以參考下2023-06-06
el-form表單el-form-item驗(yàn)證規(guī)則里prop一次驗(yàn)證兩個(gè)或多個(gè)值問(wèn)題
這篇文章主要介紹了el-form表單el-form-item驗(yàn)證規(guī)則里prop一次驗(yàn)證兩個(gè)或多個(gè)值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05

