Skip to content

Commit 93aba0f

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 93aba0f

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

src/ng/browser.js

Lines changed: 2 additions & 1 deletion
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

Lines changed: 20 additions & 2 deletions
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,22 @@ 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+
/* global BASE_HREF_REGEXP */
584+
_baseHref = href && href.replace(BASE_HREF_REGEXP, '');
585+
};
586+
570587
/**
571588
* @ngdoc event
572589
* @name ng.$location#$locationChangeStart
@@ -600,7 +617,8 @@ function $LocationProvider(){
600617
function( $rootScope, $browser, $sniffer, $rootElement) {
601618
var $location,
602619
LocationMode,
603-
baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
620+
// if base[href] is undefined, it defaults to ''
621+
baseHref = isString(_baseHref) ? _baseHref : $browser.baseHref(),
604622
initialUrl = $browser.url(),
605623
appBase;
606624

test/ng/locationSpec.js

Lines changed: 17 additions & 0 deletions
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)