Skip to content

Commit cbcc848

Browse files
committed
fix($state): use $browser.baseHref() when generating urls with .href()
If an angular app is placed in a subdirectory and a <base href="..." /> tag is used, ui-router should use the configured value when generating urls through $state.href(). Thanks to @mfield for the testing help!
1 parent 6798daa commit cbcc848

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

src/state.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -448,14 +448,15 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
448448
*/
449449
// $urlRouter is injected just to ensure it gets instantiated
450450
this.$get = $get;
451-
$get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$location', '$urlRouter'];
452-
function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $location, $urlRouter) {
451+
$get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$location', '$urlRouter', '$browser'];
452+
function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $location, $urlRouter, $browser) {
453453

454454
var TransitionSuperseded = $q.reject(new Error('transition superseded'));
455455
var TransitionPrevented = $q.reject(new Error('transition prevented'));
456456
var TransitionAborted = $q.reject(new Error('transition aborted'));
457457
var TransitionFailed = $q.reject(new Error('transition failed'));
458458
var currentLocation = $location.url();
459+
var baseHref = $browser.baseHref();
459460

460461
function syncUrl() {
461462
if ($location.url() !== currentLocation) {
@@ -830,6 +831,15 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
830831
if (!$locationProvider.html5Mode() && url) {
831832
url = "#" + $locationProvider.hashPrefix() + url;
832833
}
834+
835+
if (baseHref !== '/') {
836+
if ($locationProvider.html5Mode()) {
837+
url = baseHref.slice(0, -1) + url;
838+
} else if (options.absolute){
839+
url = baseHref.slice(1) + url;
840+
}
841+
}
842+
833843
if (options.absolute && url) {
834844
url = $location.protocol() + '://' +
835845
$location.host() +

test/stateSpec.js

+22
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,28 @@ describe('state', function () {
632632
locationProvider.hashPrefix("!");
633633
expect($state.href("home")).toEqual("#!/");
634634
}));
635+
636+
describe('when $browser.baseHref() exists', function() {
637+
beforeEach(inject(function($browser) {
638+
spyOn($browser, 'baseHref').andCallFake(function() {
639+
return '/base/';
640+
});
641+
}));
642+
643+
it('does not prepend relative urls', inject(function($state) {
644+
expect($state.href("home")).toEqual("#/");
645+
}));
646+
647+
it('prepends absolute urls', inject(function($state) {
648+
expect($state.href("home", null, { absolute: true })).toEqual("http://server/base/#/");
649+
}));
650+
651+
it('prepends relative and absolute urls in html5Mode', inject(function($state) {
652+
locationProvider.html5Mode(true);
653+
expect($state.href("home")).toEqual("/base/");
654+
expect($state.href("home", null, { absolute: true })).toEqual("http://server/base/");
655+
}));
656+
});
635657
});
636658

637659
describe('.get()', function () {

0 commit comments

Comments
 (0)