$location.search() returns undefined when base href does not match URL #16241
Description
Activity
As noted in the docs,
$locationwill indeed not work correctly in this case:The
$locationservice is not able to function properly if the current URL is outside the URL given as the base href.We could make
$locationuse a different baseHref, but link-rewriting would be broken.TBH, I am not even sure what the usecase is. Why load AngularJS on a page that doesn't match the intended
baseHref?)The canonical location is
/baz/, and any links that people copy should use that location, but sometimes it's served at other locations. Either as an alias for compatibility reasons, or it's an endpoint that's embedded by a third party or at the end of some sort of OAuth or other SSO flow, in which case the server has some extra work to do to validate that request and set context, but the angularjs application is still the same.If $location will be unable to do its job, it'd be nice if it threw an error telling us that explicitly, though I fear at this point that'd be a backward-incompatible change.
(in practice, the app does otherwise work, and only failed when we added this bit to app.run())
Yeah, changing that would be a breaking change. (We can still consider it for 1.7, but I am not convinced it is worth it (nor that it isn't).)
(in practice, the app does otherwise work, and only failed when we added this bit to app.run())
It might look like it works, but could break in subtle ways (e.g. clicks on links being handled incorrectly). It really depends on what features you depend on, but you are in dangerous waters.
You can obviously work around that, but proceed at your own risk 😁
We are going to post a warning in the console when you try to do this (rather than throwing an error). This will help developers find out why their app might not be working correctly in this case.
Reacted by Ash Clarke, Dmytro Yashyn and Elliott Regan
I'm submitting a ...
Current behavior:
In our app's
runfunction,$location.search()returnsundefined.Expected / new behavior:
$location.search()should return an object, as documented.Minimal reproduction of the problem with instructions:
Serve page at
https://localhost/foo/bar/include tag
<base href="/baz/">Use HTML5 location mode.
see http://plnkr.co/edit/RRJMNjo6Viw1NbtNeWfr?p=preview
AngularJS version: 1.5.10
Browser: Chrome 61 | Firefox 57
Anything else:
Oh, this may be a duplicate of #11223. That issue got sidetracked to a discussion of case-sensitivity and then marked as wontfix, but I think that was a tangent unrelated to making search() return properly.
In a way much like #14488 noted for$location.$ $absUrl, the $location.$ $search property may not be initialized before $location.search() is called.
Perhaps the search() method needs to check to see if $$search is undefined, similar to how other functions check for a value for $$path or $$hash, or perhaps when $locationProvider.$get needs to always call$location.$ $parse (which $location.$ $parseLinkUrl declines to do in this condition).
I also noticed that sometime later $location.search() would return properly; I suspect this is related to how $locationProvider.$get adds a watch to $rootScope, but the app's run function probably happens before that digest cycle.