I just posted one yesterdayNew front-end cross-domain solutionTry it, I encountered problems in development today.
cause
The front-end is usingvue-routerComponenthistory
mode, 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 visittest
Jumped 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 <base> tag var baseEl = ('base'); base = (baseEl && ('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 thisbase
Parameters are instantiated byVueRouter
Incoming 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 taghref
value 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://test
Such 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 && onComplete(route); }, onAbort); }; //Lines 561~Lines 563function cleanPath (path) { return (/\/\//g, '/') }
It's happeningpushState
Before, 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/test
When 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.