Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

fix($location): consider baseHref in relative link for legacy browsers #8233

Closed
wants to merge 6 commits into from
7 changes: 7 additions & 0 deletions src/ng/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,13 @@ function $LocationProvider(){
if (href.indexOf('://') < 0) { // Ignore absolute URLs
var prefix = '#' + hashPrefix;
if (href[0] == '/') {
// Account for base href already present in appBase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// use baseHref variable is fine

if (!baseHref && href.indexOf(baseHref) === 0) {
href = href.substr(baseHref.length);
if (!href || href[0] != '/') {
href = '/' + href;
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! I've updated accordingly

if (baseHref && href.indexOf(baseHref) === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is quite right.

Assuming we have a base tag like <base href="http://www.google.com/foo/bar">,

<a href="/baz" id="a">baz</a> should resolve to http://www.google.com/baz,
<a href="baz" id="a2">baz2</a> should resolve to http://www.google.com/foo/baz (not /foo/bar/baz as you might expect, because the base tag doesnt' end with a slash)

The issues are, 1) we're not really correctly resolving relative to the baseURI for absolute references, and 2) we're not resolving relative URIs correctly this way at all, because this branch is only ever evaluated for absolute uris (uris beginning with a /).

We need to fix this up

href = href.substr(baseHref.length);
if (!href || href[0] != '/') {
href = '/' + href;
}
}
// absolute path - replace old path
absHref = appBase + prefix + href;
} else if (href[0] == '#') {
Expand Down
31 changes: 31 additions & 0 deletions test/ng/locationSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,37 @@ describe('$location', function() {
}).not.toThrow();
});
});


it('should transform the url correctly when a base path is present and html5mode is enabled but not supported', function() {
var serverUrl, base;
module(function() {
return function($browser) {
serverUrl = 'http://server';
base = '/foo/bar'
$browser.url(serverUrl + base);
$browser.$$baseHref = base;
};
});
inject(initService(true, '', false), function($rootScope, $compile, $browser, $rootElement, $document, $location) {
// we need to do this otherwise we can't simulate events
$document.find('body').append($rootElement);

$rootElement.append('<a href="/foo/bar/view1">v1</a><a href="/foo/bar/baz/view2">v2</a><a href="/view3">v3</a>');
var av1 = $rootElement.find('a').eq(0);
var av2 = $rootElement.find('a').eq(1);
var av3 = $rootElement.find('a').eq(2);

browserTrigger(av1, 'click');
expect($browser.url()).toEqual(serverUrl + base + '#/view1');

browserTrigger(av2, 'click');
expect($browser.url()).toEqual(serverUrl + base + '#/baz/view2');

browserTrigger(av3, 'click');
expect($browser.url()).toEqual(serverUrl + base + '#/view3');
});
});
});


Expand Down