When we use front-end rendering like Vue or React, there are usually two types of routing: hash routing and history routing.
- hash routing: listen to the hash changes in the url and render different content, this kind of routing does not send requests to the server and does not need server-side support.
- history routing: listens for changes in the path in the url and requires the support of both the client and the server.
Let’s implement these two types of routes step by step to understand the underlying implementation principles in depth. We mainly implement the following simple functions.
- listen to changes in the route and can make actions when the route changes.
- the ability to move forward or backward.
- can configure routes.
1. hash routing
When the hash of a page changes, it will trigger the
hashchange event, so we can listen to this event to determine if the route has changed.
1.1 The process of implementation
After splitting oldURL and newURL, we can get more detailed hash values. We’ll start by creating a HashRouter class.
hashchange is only triggered when the hash changes, and it is not triggered when we first enter the page, so we also need to listen to the
load event. Note that the event of the two events is different: the event in the hashchange event has two properties, oldURL and newURL, but the event in the load event does not have these two properties, but we can get the current hash route through location.hash.
Up to this point it has been possible to get the current hash route, but when the route changes, our page should switch, so we need to listen for this change.
1.2 The way to call
By now, we have the basic functionality done. Let’s match it with an example to get a better image.
See [Sample of hash routing].
2. history routing
In history routing, we will definitely use the methods in
window.history, the common actions are
- back(): go back to the previous route.
- forward(): advance to the next route, if any.
- go(number): go to any route, positive number for forward, negative number for backward.
- pushState(obj, title, url): advances to the specified URL without refreshing the page.
- replaceState(obj, title, url): replaces the current route with the url, without refreshing the page.
When calling these methods, all will just modify the URL of the current page, and the content of the page will not change at all. If an interviewer asks the question “how to modify the URL of a page without sending a request”, the answer is these 5 methods. then the answer is these 5 methods.
If there is no new updated URL on the server side, a browser refresh will report an error, because a browser refresh will actually send an http web request to the server. So to use history routing, you need the support of the server.
2.1 Application scenarios
What is the difference between the pushState and replaceState methods and location.href and location.replace methods? What are the application scenarios?
- location.href and location.replace send a request to the server when switching, while pushState and replace only modify the url, unless a request is initiated.
- the feature that only switches the url without sending a request can be used in front-end rendering, for example, the home page is rendered server-side and the secondary page is rendered front-end.
- the possibility of adding animations for route switching.
- when using a scenario like Jitterbug in the browser, the corresponding URL can be silently modified when the user slides to switch videos, and when the user refreshes the page, it can still stay in the current video.
2.2 Unable to listen for route changes
When we use history routing, we must be able to listen for changes to the route. There is a global
popstate event, which has a state keyword in its name, but when
replaceState are called, the popstate event is not triggered, only the first 3 methods listed above are triggered. You can click popState does not trigger popstate event to see it.
In this case, we can use
window.dispatchEvent to add an event.
Then you can add a listener for both methods.
2.3 The complete code
The complete code is as follows.
The usage is the same as hash routing above, so we won’t go into details here. Click to see the application of history routing.
At this point, the principle and implementation of the two routing methods are introduced.