What is routing

The idea of routing first came from the back end. You’ve often seen this in the past when developing pages with template engines

http://hometown.xxx.edu.cn/bbs/forum.php
Copy the code

Sometimes there will be a path with.asp or.html, this is called SSR(Server Side Render), through the Server Side, directly back to the page.

And the response goes like this

1. The browser sends a request

2. The server listens for a request from port 80 (or 443) and parses the URL path

3. According to the routing configuration of the server, return the corresponding information (can be HTML strings, JSON data, images, etc.)

4. How do browsers parse data packets based on their Content-Type

To put it simply, routing is a way to interact with back-end servers. It is one of the functions of routing to request different resources and pages through different paths.

The origin of front-end routing

Ajax, Asynchronous JavaScript And XML, is a technical solution that browsers use to implement Asynchronous loading. In the early 1990s, most web pages were returned to HTML directly, and users had to refresh the page every time they updated. With the development of network, there is an urgent need for a scheme to improve this situation.

In 1996, Microsoft first introduced the iframe tag, which introduced the concept of asynchronous load and request elements, and then in 1998, Microsoft’s Outloook Web App team came up with the basic concept of Ajax (a precursor to XMLHttpRequest), This technology is implemented in Internet Explorer 5 via ActiveX. After Microsoft implemented this concept, other browsers like Mozilia, Safari, and Opera implemented Ajax with XMLHttpRequest. However, when IE7 was released, Microsoft chose to compromise and accommodate the implementation of XMLHttpRequest.

With Ajax, user interaction doesn’t have to refresh the page every time, and the experience is vastly improved.

But it was Google Maps that really took the technology to the next level, unleashing the true power of Ajax and unleashing the imagination of many developers beyond simple data and page interactions, paving the way for asynchronous interactive experiences to flourish.

A more advanced version of the asynchronous interaction experience is SPA (so, what is the highest level of asynchronous interaction experience? Will be revealed at the end of this article) — single page app. Single-page application is not only refresh-free in page interaction, even page jump is refresh-free, in order to achieve single-page application, so there is front-end routing.

The concept of single-page applications came with MVVM. It was first proposed by Microsoft, and then they implemented Knockoutjs in the browser. But the power of the technology was not fully appreciated by developers at the time, perhaps because Knockoutjs implementations were too complex to spread widely.

See the implementation principle of front-end routing from vue-Router

The implementation of front-end routing is actually quite simple.

Essentially, it detects url changes, intercepts URL addresses, and parses them to match routing rules.

But then someone might ask: Does the URL refresh the page every time it changes? How does JavaScript detect and intercept urls when the page is refreshed?

Prior to 2014, routing was done with hashes, and URL hashes are similar to this

https://segmentfault.com/a/1190000011956628#articleHeader2

This #. Subsequent hash changes do not cause the browser to make a request to the server, and the browser will not refresh the page if it does not make a request.

To clarify, if we were to implement a route using a hash pattern, the flow would look like this.

Hash is relatively easy to implement and does not require server support.

In addition, we can refer to the implementation of vue-Router

/** * Adds listeners for URL hash changes */ setupListeners () {const router = this.router /** * Resolves the path whenever the hash changes * matches the route */ window.addEventListener('hashchange', () => { const current = this.current /** * transitionTo: * Matches the route * and passes the route configuration, Render new page to uI-view node */ this.transitionto (getHash(), route => {replaceHash(route.fullpath)})}Copy the code

When a hash change is detected, the page can be replaced by replacing the DOM.

Fourteen years later, the HTML5 standard was released. Two new apis, pushState and replaceState, allow you to change urls without sending requests. There’s also an onPopState event. This allows you to implement front-end routing in a different way, but in the same way that you implement hash. With HTML5 implementations, single-page routing urls don’t have an extra #, making them more aesthetically pleasing. But because there are no # numbers, the browser still sends a request to the server when the user does something like refresh the page. To avoid this, the implementation requires server support to redirect all routes to the root page. See: HTML5 Histroy mode

Again, let’s clarify our thinking so that we can write code more easily

This part of vue-Router source code, you can find that the implementation of the idea is generally the same

export class HTML5History extends History { constructor (router, base) { super(router, Base) /** * works just like a hash implementation * matches routes by listening for popState events *, Then update the page DOM */ window.adDeventListener (' popState ', e => { const current = this.current // Avoiding first `popstate` event dispatched in some browsers but first // history route not updated since async guard at the same time. const location = getLocation(this.base) if (this.current === START  && location === initLocation) { return } this.transitionTo(location, route => { if (supportsScroll) { handleScroll(router, route, current, true) } }) }) } go (n) { window.history.go(n) } push (location, onComplete, onAbort) { const { current: FromRoute} = this this.transitionto (location, route => {// Using pushState to update the URL does not cause the browser to send the request, PushState (cleanPath(this.base + route.fullPath)) onComplete && onComplete(route)}, onAbort) } replace (location, onComplete, onAbort) { const { current: FromRoute} = this this.transitionto (location, route => {// replaceState = pushState) ReplaceState (cleanPath(this.base + route.fullPath)) onComplete && onComplete(route)}, onAbort)}}Copy the code

You can also install the package via NPM (functionality is fully implemented and well documented)

npm i router -S
Copy the code

Afterword.

What is the highest level of asynchronous interaction experience?

PWA, so that the front page can be offline operation