-
Notifications
You must be signed in to change notification settings - Fork 3k
html5Mode appears not to work #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Well, the sample app currently uses plain anchors to do most of the navigation. If you're using html5 mode, this means the browser will actually try to load e.g. '/sample/contacts/1' and get a 404 because there is no such file. You'd have to configure the server to rewrite any URL under /sample/ to /sample/index.html. However this would still cause a full page reload -- you'd also need a click handler on every link to do a preventDefault() and call $state.transitionTo() to perform the transition instead of letting the browser update the location itself. Doing this automatically is something we should look at in relation to the planned directive for generating hrefs. |
The problem isn't URL rewriting nor is it click handling...URL rewriting is fine with me, and of course necessary for HTML5 mode. angular core takes care of the rest (unless for some reason the custom view needs also to do so). The main/big problem is that when I load /sample it ui-router is confused by the lack of # in the URL -- essentially, it seems not to "know where the base URL of the app is" and tramples its way up the path to the root of the server. I'm confused about how your answer relates to the other issue where you stated that HTML5 mode should "just work". It now sounds like you're saying that a bunch of work on ui-router for hrefs and clicks is necessary before it will work... did new information come to light? The hrefs seem to work properly and the browser is not reloading pages from the server to the best of my knowledge, so I think that if ui-rotuer respects the app root then all will be well. |
P.S. If my comments aren't clear, one way to see the issue for yourself is to update those three lines of code... I'm assuming this behavior isn't desired and that the fix would hopefully be easier than all of the nasty stuff you mentioned in your comment :) -- I just can't understand what all is going on with the "rules" array in the code enough to know why it is choosing to transition to "/". |
I've had this same issue. To resolve it, I had to do this: app.config ["$locationProvider", "$routeProvider", ($locationProvider, $routeProvider) ->
$locationProvider.html5Mode(true)
$routeProvider.when "/",
controller: ["$state", ($state) ->
$state.transitionTo("catalogue.popular")
]
] Basically, it seems that in html5Mode, ui-router will fail to identify the route at bootstrap-time and the starting route needs to be bootstrapped using $routeProvider. I don't know if this is a bug or feature though! |
It certainly looks like a bug to me. It seems like your solution will work around the initial bounce to the root of the server, but does it fix any deeper states? Does it allow deep linking? I'm compelled to say, as a potential adopter, that I'm a little scared that the team seems not to have noticed this behavior. I'm not trying to be picky and I know this is prerelease, but is html5 history support on the roadmap? It would seem that if this issue lingers it could fester in the codebase, since it's a routing problem and this is all about routing. I wish I could understand the method of constructing the rules array. I don't know how many assumptions about the presence of a pound sign are in there. |
If you switch to html mode, you will need quite some restructuring.... one example is that when you have the sample, you have the path another way is ofc. (properly) to switch all routes to comply with the "sample" subfolder, so At least in my own angular-router, starting the dev-server (grunt-contrib-connect) in the sample app I wanted to switch to html5mode, then moving all sources that was located outside that path into a local path worked for it... But as I said, quite some restructuring. |
Thanks, @jeme, I'm not entirely sure whether you're indicating that the sample would need restructuring or the router would need restructuring. I'll write a test case and post back with a link to my branch. If the team wants to fold in the test case, great. I really hope html5 mode support can be worked in (assuming that we're talking about something other than just the sample not doing the right thing). |
Note: I don't think the correct behavior is to interpret paths relative to the server root in HTML5 mode... or is it? |
@stu-salsbury I haven't tried it with ui-router, but in angular-routing's case, it was purely the sample that was broken for html5 mode... And yes, at least for routes it is the correct behavior to see the path relative to the domain, as you can't see the difference as there is no # to separate you from the "routing route" and the "actual route". So instead of have the following stack of locations:
you would have:
And how will you know that you need to work relative to: All possible paths must return the same root index.html from the server, no matter the path... this is what @ksperling is talking about... not sure if the simple web-server in grunt-contrib-connect is capable of that... But as you see, html5mode brings allot of things to think about from an application standpoint, all routes needs to be accepted by the server as well as the client, the server can obviously in all cases serve the same file, but it still has to detect that... This also means you have to think about actual server calls, like serving templates, REST service calls and so forth... You would properly go ahead at set your server up to do something like:
(and important that it's in that order, so the last one doesn't hijack the others) You may also wan't to read about the $location service and html5 mode here: http://docs.angularjs.org/guide/dev_guide.services.$location |
I understand URL rewriting and the necessity of it for deep linking in html5 history mode. I think we can put that part aside. Maybe I should work on proving to myself that html5 history mode does indeed work the way I think it does in the core router. Perhaps I imagined it. |
@stu-salsbury you could use url-rewritting as well, but the above was actually server side routing, which is the concept I use in ASP.NET to serve pages... But ui-router (as well as angular-routing) is just using
So the rest is up to the $location service and it's implementation. So I doubt we can do anything different. But if you find something I would absolutely like to know so I can have a look. If you use server side routing, it can't even tell where the index.html really came from, it would just think that all those resources happened to serve the exact same file, so it would look like the file was copied out all over the server from the browsers point of view. |
Ok, tested the default router again. It does indeed require that routes be prefixed with the path to the app root I think I must have been remembering ember behavior, which if true, ember must be determining the app path based on the location of index.html. I guess that's not a feature of angular, so my bad for that. I'll focus my tests without that assumption. Thank you for pointing that out. |
@stu-salsbury I would consider that a just as error prone approach, because as I mentioned above, if you use server side routing to construct your response, the client wouldn't be the wiser to where index.html existed... It would think it existed in all the paths that returned it... (Index.html might actually not even exist in a server path at all, could be stored in a database or something completely different)... So server side routing seems like it would break Ember on that if that is the case. But that is a completely different topic, and as interesting that may be, it's off-topic... Let me know if you still have trouble with figuring html5mode out. |
I put so much FUD into this, I'm going to close the issue. I'm sorry for the noise. I'll open a new one with a test case implemented if there is still some demonstrable problem. The issue of how one could detect the app path under a URL-rewriting scenario seems basically to be moot unless the ui-router wants to break from the core's behavior, which may not be wise. EDIT: I think I just figured out the problem originally brought me into the quagmire of of this non-issue. It seems that maybe the paths to the templates are relative to the route, not to the app path nor the server root. Now that I've got that figured out, html5 mode works for me. |
I think both of you are missing the easy solution to this issue which is the Here is something I've been working on that uses this approach: http://embed.plnkr.co/Qv0uCROy1jbAmhjQ2TkR/preview (Note, it may do 'nothing' if my dev server is offline at the time you check, but the code is all there). |
I don't have the references at hand at the moment, but there was a fair bit of discussion on some angular lists and issues around base href having unintended side effects, e.g. anchor-only hrefs become relative to the base href as well. It seems what's need is a way to set a base href purely for $location. |
Also running into this problem and haven't found an answer. If I'm always providing the index.html page no matter the link to a nested state, then it's always looking for url additions to that link (of which there are always none)... can we see an example of this working? |
My fix for this - spending a lot of time to debug and stumbling across this when comparing my code to the sample app - is this: in the config function of your angular app: $locationProvider.html5Mode(true).hashPrefix('!'); Then when I try to reload the page I get nothing... I then add this to my html header: <base href="/"> Bam, I get pages that reload correctly and clean URLs.
|
whoa don't know how this works (prefix '!'?) but |
not working in angular 1.2.20 |
This doesn't seem to work in Angular 1.3.0 either |
while implementing "$locationProvider.html5Mode(true).hashPrefix('!');". When i refresh the page eg: url: localhost:8000 /project. |
I am facing the same issue. I am using angular-ui router 0.27 version with angularJS 1.2.21 version. When I turn on html5 mode to true and use and try to reload the page, I get following error "Unable to load the webpage because the server sent no data." Error code: ERR_EMPTY_RESPONSE. I am trying to get bookmarking working and for that I had to go away from hashes in the URL so that the server receives the complete url. Please re-open this defect. |
As far as I can tell, html5 mode works as advertised. Show me what bug there is. |
If you try to use urlRouteProvider with html5Mode, you might reproduce the problem. |
@pengzewen show me. |
turns out it's the issue of apache configuration. you are right, it works as the description in documentation.
|
@christopherthielen I am getting same issue.. |
Finally I got a way to to solve this issue by server side as it's more like an issue with AngularJs itself I am using 1.5 Angularjs and I got same issue on reload the page.
|
(note I've edited this since I first posted it)
I was happy to see from #69 that html5Mode should just work. It doesn't work for me with the sample in Chrome or Firefox. I haven't tested any other browser.
Steps:
http://localhost:3006/sample
everything works.
change three lines in index.html (starting at line 50)
After that change, when I go to /sample the content for that page loads and displays properly and then I'm "location.replaced" to "/" and everything ceases to function.
I tried to figure out where things head south but I just don't know the code well enough.
Top level routes and their dynamic segments do work if I copy the build and lib directories into the sample directory and change the paths to them, but deeper routes do not (e.g. /contacts/1 works but /contacts/1/item/a does not).
The text was updated successfully, but these errors were encountered: