Skip to content

Commit ac1dc9d

Browse files
committed
fix($location): support alternative means of setting application base path
In HTML, the <base> tag is used to configure how relative hyperlinks are resolved. In Angular, it has another use, configuring how URLs are rewritten. Because of this, setting the base URL to some external path outside of the application would cause $location.$$parse() to throw (which is the desired behaviour). This change enables developers to imperatively configure the application basePath, taking advantage of the natural HTML use of the <base> tag without breaking Angular applications. Example: ``` angular.module("test", []) .config(function($locationProvider) { $locationProvider.baseHref("http://foo.com/the/base/application/path/"); }); ``` Closes angular#4442
1 parent 95522cc commit ac1dc9d

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

src/ng/browser.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
'use strict';
2+
var BASE_HREF_REGEXP = /^(https?\:)?\/\/[^\/]*/;
23

34
/**
45
* ! This is a private undocumented service !
@@ -253,7 +254,7 @@ function Browser(window, document, $log, $sniffer) {
253254
*/
254255
self.baseHref = function() {
255256
var href = baseElement.attr('href');
256-
return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
257+
return href ? href.replace(BASE_HREF_REGEXP, '') : '';
257258
};
258259

259260
//////////////////////////////////////////////////////////////

src/ng/location.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,8 @@ function locationGetterSetter(property, preprocess) {
531531
*/
532532
function $LocationProvider(){
533533
var hashPrefix = '',
534-
html5Mode = false;
534+
html5Mode = false,
535+
_baseHref;
535536

536537
/**
537538
* @ngdoc property
@@ -567,6 +568,21 @@ function $LocationProvider(){
567568
}
568569
};
569570

571+
/**
572+
* @ngdoc property
573+
* @name ng.$locationProvider#baseHref
574+
* @methodOf ng.$locationProvider
575+
* @description
576+
* In situations where it is desireable to specify an external URL within the `<base>` tag, for
577+
* simplifying access to external resources, this configuration method will override the <base>
578+
* tag and enable location rewrites to work as expected;
579+
*
580+
* @param {string} href Base application url
581+
*/
582+
this.baseHref = function(href) {
583+
_baseHref = href && href.replace(BASE_HREF_REGEXP, '');
584+
}
585+
570586
/**
571587
* @ngdoc event
572588
* @name ng.$location#$locationChangeStart
@@ -600,7 +616,8 @@ function $LocationProvider(){
600616
function( $rootScope, $browser, $sniffer, $rootElement) {
601617
var $location,
602618
LocationMode,
603-
baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
619+
// if base[href] is undefined, it defaults to ''
620+
baseHref = isString(_baseHref) ? _baseHref : $browser.baseHref(),
604621
initialUrl = $browser.url(),
605622
appBase;
606623

test/ng/locationSpec.js

+17
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,23 @@ describe('$location', function() {
12561256
}).not.toThrow();
12571257
});
12581258
});
1259+
1260+
1261+
it('should use $locationProvider.baseHref() as base url if available', function() {
1262+
module(function($locationProvider) {
1263+
$locationProvider.baseHref("http://host.com/ngApp/");
1264+
$locationProvider.html5Mode(true);
1265+
return function($browser, $rootElement, $document){
1266+
$browser.url("http://host.com/ngApp/");
1267+
$browser.$$baseHref = "http://server/assets";
1268+
};
1269+
});
1270+
1271+
inject(function($rootScope, $location, $browser) {
1272+
expect(function() { $location.$$parse($location.$$rewrite("http://host.com/ngApp/routeA")); }).not.toThrow();
1273+
expect($location.path()).toBe('/routeA');
1274+
});
1275+
});
12591276
});
12601277

12611278

0 commit comments

Comments
 (0)