SoFunction
Updated on 2025-04-04

About vue-router path calculation problem

I just posted one yesterdayNew front-end cross-domain solutionTry it, I encountered problems in development today.

cause

The front-end is usingvue-routerComponenthistorymode, but since our entire page is loaded from static (static resource station), other pages naturally need to be picked up across domains, but there is a problem with vue-router when cross-domain.

Analyze the problem

Our API site is

The static resource is in , and the base tag of the page also points to static

<base href="" rel="external nofollow" />

However, on visittestJumped to the template/http://test

After some simple breakpoint debugging, the following code was locked

[source]: /vuejs/vue-router/blob/dev/dist/

 [][source]

// Line 1794~ Line 1675function normalizeBase (base) {
 if (!base) {
  if (inBrowser) {
   // respect &lt;base&gt; tag
   var baseEl = ('base');
   base = (baseEl &amp;&amp; ('href')) || '/';
  } else {
   base = '/';
  }
 }
 // make sure there's the starting slash
 if ((0) !== '/') {
  base = '/' + base;
 }
 // remove trailing slash
 return (/\/$/, '')
}

The purpose of this code is to set the base path of the route. If you are interested in tracking it all the way, you will find thisbaseParameters are instantiated byVueRouterIncoming at the time

Looking at the code again, he will judge that if the base is empty, then he will give a default value:

If it is executed in the browser (non-server environment), it will be called('base')Come try to get<base href='' />In the taghrefvalue of the attribute;

In our actual scenario, here we get an absolute address across domains, and then immediately afterwards

 if ((0) !== '/') {
  base = '/' + base;
 }

When the first character of the url is not/When adding/, it's very obvious here is a bug

Mine is the absolute addressThe first character is of course not/, so it was from the previous one/http://testSuch a website

Revise

if(/^([a-z]+:)?\/\//(base)){

}else if ((0) !== '/') {
 base = '/' + base;
}

In order to minimize the source code, an empty if is added here. When the url is started by the protocol, it is considered an absolute path.

* Another form of absolute path is //

test

After the first modification, there is still a problem with accessing the page again, and the page you are visiting is still/http://test

Continue to analyze

After tracking the source code again, I found

[][source]

// Line 2006~ Line 2016  = function push (location, onComplete, onAbort) {
  var this$1 = this;

  var ref = this;
  var fromRoute = ;
  (location, function (route) {
   pushState(cleanPath(this$ + ));
   handleScroll(this$, route, fromRoute, false);
   onComplete &amp;&amp; onComplete(route);
  }, onAbort);
 };
//Lines 561~Lines 563function cleanPath (path) {
 return (/\/\//g, '/')
}

It's happeningpushStateBefore, he would deal with the url againcleanPath

And the processing here is simpler, more rude, and has bigger problems.

He directly slashes 2//Replace with 1 slash/, What should I do if there are 3 slashes in a row?

So dealing with it/testWhen the address is, it will be processed ashttp://test It's a relative path again...

Continue to modify

function cleanPath (path) {
  var ishttp = /^([a-z]+:)?\/\//(path);
  var http = (ishttp) ? ishttp[0] : '';
  return http + ().replace(/\/{2,}/g, '/');
}

If the protocol starts, after excluding the content of the protocol, replace 2 or more slashes that are consecutively together with 1 slash.

** Complete the submission pull

/vuejs/vue-router/pull/1353/files

By the way, vue-router's url processing is really too rough...

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.