HTML5 client routing
Deep links to client side applications using frameworks that make use of HTML5 routing, such as Angular, can be problematic. The web browser client side application utilizes regular URL paths for client side application navigation that appear in the browser address to be locations of actual resources. This however is not the case, the running application in the browser makes use of javascript pushstate to navigate to states within the client side application and does not request the resource shown in the browser address bar when running. All of this causes no issues until the user takes an action that causes the browser to intiate a request to the nonexisting resource in the address bar. For example, the user may bookmark a deep link into the application or press the reload button if the application is performing slowly.
To accomodate this the web server requires some understanding of the state routing used in the browser address bar by the application. In the progress of porting Frozen Particle Waves this issue was noticed in a few scnearios. The Angular web application is packaged into a single Spring Boot jar and is usually fronted by Apache. I will demonstrate how to configure rewrite rules in apache2 that can accomodate requests for resources that represent the client side application state.
An example
Frozen Particle Waves Angular version has a base path of /fpw2 and client side state routes of /fpw2/login and /fpw2/fpw-app/*. Other paths within the application under /fpw2 are for resources, api calls and other artifacts such as javascript maps. Initially without the change requests to /fpw2/ on the server would correctly bootstrap the client side application and send the unauthenticated user to /fpw2/login. This works fine unless the user performs an action like describe above. When one of those actions is performed the web browser requests a non existant resource and receives a 404 error page from the Spring Boot application.
Apache configuration solution
We need any request to the HTML5 added routes that is for client side state navigation to return the client side application without changing the URL so that the client side app will bootstrap and then see the navigation state in the URL. This can be done with ReWrite rules in apache.
This example makes use of the apache rewrite engine so make sure it is enabled and turn RewriteEngine on in the configuration file before using these apache2 configuration rules. The configuration uses a loction block. The apache2 configuration location block allows us to define rules that match a location as represented in the URL. These RewriteRules change the urls before they match the ProxyPass lines below. The rules rewrite the login page to request the root unnamed file when /fpw2/login is requested. Another rewrite rule is used to handle any requested resourcesfrom items under /fpw2/fpw-app. The requests now modified as needed are sent to the ProxyPass directive to pass them to the application for processing.
|
|
Conclusion
This solves the deep linking and bookmarking of HTML5 routes requested by the browser when using apache2. It is important to also include an html base element when using this approach to solve deep links to HTML5 routing locations so that the other resources of the page are rquested with the correct relative location regardless of the browsers apparent location of the loaded index.html single page application.