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

Commit

Permalink
fix($location): default to / for the url base if no base[href]
Browse files Browse the repository at this point in the history
With the recent refactoring of $location service we changed this behavior
resulting in a regression.

Previously we thought that html5 mode always required base[href]
to be set in order for urls to resolve properly. It turns out that
base[href] is problematic because it makes anchor urls (#foo) to
always resolve to the base url, which is almost always incorrect
and results in all anchors links and other anchor urls (e.g. svg
references) to be broken.

For this reason, we should now start recommending that people just
deploy to root context (/) and not set the base[href] when using
the html5 mode (push/pop history state).

If it's impossible to deploy to the root context then either all
urls in the app must be absolute or base[href] must be set with the
caveat that anchor urls in such app won't work.

Closes #2762
  • Loading branch information
IgorMinar committed Jun 25, 2013
1 parent 0960cd0 commit aef0980
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/ng/location.js
Expand Up @@ -69,7 +69,7 @@ function stripFile(url) {
return url.substr(0, stripHash(url).lastIndexOf('/') + 1);
}

/* return the server only */
/* return the server only (scheme://host:port) */
function serverBase(url) {
return url.substring(0, url.indexOf('/', url.indexOf('//') + 2));
}
Expand Down Expand Up @@ -497,12 +497,12 @@ function $LocationProvider(){
function( $rootScope, $browser, $sniffer, $rootElement) {
var $location,
LocationMode,
baseHref = $browser.baseHref(),
baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
initialUrl = $browser.url(),
appBase;

if (html5Mode) {
appBase = baseHref ? serverBase(initialUrl) + baseHref : initialUrl;
appBase = serverBase(initialUrl) + (baseHref || '/');
LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url;
} else {
appBase = stripHash(initialUrl);
Expand Down
13 changes: 13 additions & 0 deletions test/ng/locationSpec.js
Expand Up @@ -635,6 +635,19 @@ describe('$location', function() {
}
);
});


it('should set appBase to serverBase if base[href] is missing', function() {
initService(true, '!', true);
inject(
initBrowser('http://domain.com/my/view1#anchor1', ''),
function($rootScope, $location, $browser) {
expect($browser.url()).toBe('http://domain.com/my/view1#anchor1');
expect($location.path()).toBe('/my/view1');
expect($location.hash()).toBe('anchor1');
}
);
});
});


Expand Down

2 comments on commit aef0980

@fessyfoo
Copy link

Choose a reason for hiding this comment

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

also Closes #2799? Though I suggest also allowing setting of appBase from $locationProvider then an application can configure app base without using base[href], as suggested by @jeme in #2799

@fessyfoo
Copy link

Choose a reason for hiding this comment

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

A Note to those who build the bleeding edge to get this commit, and are also using $routeProvider. this commit and on contain a refactoring of the $routeProvider into it's own module. you'll have to add angular-route.js to your project and also add ngRoute as a dependency to your app.

Please sign in to comment.