Home >Web Front-end >HTML Tutorial >What is front-end routing and its explanation

What is front-end routing and its explanation

小云云
小云云Original
2018-02-10 10:19:484105browse

What is front-end routing

The so-called front-end routing has the ability that the client browser can render different view pages based on different URLs without relying on the server.

The rationality of the existence of front-end routing

Before the sword of Ajax was revealed and the front-end was still in its infancy, the routing The work is handed over to the backend. When switching pages, the browser sends different <span style="font-size: 14px;">url</span> requests; when the server receives the browser's request, it parses the different <span style="font-size: 14px;">url</span> to splice the required <span style="font-size: 14px;">html</span> or template, and then return the result to the browser for processing render.

Server-side routing is also unconventional and has pros and cons. Its advantage is higher security and stricter control over page display. This is useful in certain scenarios, such as an order payment process, where each step can only be reached after the previous step has been successfully executed. This can add a verification mechanism to each step of the process on the server side, and only the correct page will be returned if the verification is passed. So the front-end routing cannot implement verification at every step? Of course not, I believe that your code can be written very rigorously to ensure that the process will not go wrong under normal circumstances, but another fact that has to be faced is: the front end has no security at all. Users can modify the code at will to enter different processes, and you may add a lot of processing logic for this. In comparison, of course, the access rights to the back-end control page are safer and simpler.

On the other hand, back-end routing undoubtedly increases the load on the server side and requires <span style="font-size: 14px;">reload</span> pages, users The experience is actually not good.

In this way, front-end routing will come into play. First of all, its emergence undoubtedly reduces the pressure on the server side. Especially for a more complex application, or to be more precise, for an application with a complex routing system, the server needs to execute a piece of processing logic for each different URL, which is a bit unbearable in high concurrency situations. Secondly, there is no need to refresh the entire page when switching pages. There is no network delay and no flickering refresh, which improves the user experience.

Front-end routing implementation method

Now that the goal is achieved, what are the problems we need to solve? We can break down the problem into a little more detail, first make a small plan of 100 million, and then move on to the next step after realizing it:)

  • On the premise that the page does not refresh Implement <span style="font-size: 14px;">url</span>change

  • capture## Changes to #url<span style="font-size: 14px;"></span> in order to perform page replacement logic<span style="font-size: 14px;"></span>

How to implement updates<span style="font-size: 14px;"></span>url <span style="font-size: 14px;"></span>And the page does not refresh<span style="font-size: 14px;"></span>

As mentioned before, one feature of front-end routing compared to back-end routing is that the page does not refresh completely. Switch views. The page <span style="font-size: 14px;"></span>url<span style="font-size: 14px;"></span> has changed, but it has not been reloaded! It may seem a little weird, but it’s actually no big deal. <span style="font-size: 14px;"></span>

Imagine using the browser address bar as an input box. What we need to achieve is to change the <span style="font-size: 14px;"></span>value<span style="font-size: 14px;"></span>But do not trigger the operation of requesting the page, so that the new page will not be reloaded. If changing the value of the input box and sending the request were an atomic operation, we would be helpless. Fortunately, the request will not be sent until we hit Enter (this is obvious). Therefore, this creates conditions for us to modify the value of the address bar without triggering a page request refresh. Does BOM provide a method to modify the browser address bar <span style="font-size: 14px;"></span>url<span style="font-size: 14px;"></span> without triggering a request operation? <span style="font-size: 14px;"></span>

Here, there are two ways to meet the needs. One is to use the <span style="font-size: 14px;">#url</span> field in <span style="font-size: 14px;">hash</span>; the other is to use History API provided by HTML5.

<span style="font-size: 14px;">hash</span>Way

Understand<span style="font-size: 14px;">http</span>Protocol will know that <span style="font-size: 14px;">url</span> has many components, such as protocol, host name, resource path, query field, etc. etc., which contains a section called a fragment, identified by <span style="font-size: 14px;"></span>#.

For example: <span style="font-size: 14px;">http://www.gmail.com/text/#123</span>, <span style="font-size: 14px;">123</span> is the <span style="font-size: 14px;">hash# in </span><span style="font-size: 14px;">url</span><span style="font-size: 14px;"> </span>##part. <span style="font-size: 14px;"></span>

Open the console and enter <span style="font-size: 14px;"></span>location.hash<span style="font-size: 14px;"></span>, you can get the current <span style="font-size: 14px;"></span># The <span style="font-size: 14px;"></span>#hash<span style="font-size: 14px;"></span> part of ##url<span style="font-size: 14px;"></span> (if the current <span style="font-size: 14px;"></span>url<span style="font-size: 14px;"></span>If <span style="font-size: 14px;"></span>hash<span style="font-size: 14px;"></span> does not exist, an empty string will be returned). Next, enter <span style="font-size: 14px;"></span>location.hash = '123'<span style="font-size: 14px;"></span>, and you will find the <span style="font-size: 14px;"></span>url in the browser address bar. <span style="font-size: 14px;"></span> has changed, and the <span style="font-size: 14px;"></span>#123<span style="font-size: 14px;"></span> field has been added at the end, and the page has not been refreshed. Obviously, this meets our requirements. <span style="font-size: 14px;"></span>

history API

<span style="font-size: 14px;"></span>

HTML5 introduces a

<span style="font-size: 14px;"></span>history<span style="font-size: 14px;"></span> object , contains a set of APIs for accessing browser history, which can be accessed through <span style="font-size: 14px;"></span>window.history<span style="font-size: 14px;"></span>. <span style="font-size: 14px;"></span>

Here we are interested in its two API methods:

<span style="font-size: 14px;"></span>pushState<span style="font-size: 14px;"></span> and <span style="font-size: 14px;"> </span>replaceState<span style="font-size: 14px;"></span>.

<span style="font-size: 14px;">history.replaceState(dataObj, title, url);<br/>history.pushState(dataObj, title, url);<br/></span>

As shown above, they receive exactly the same parameters, both operate on the browser's history stack, push the passed url and related data onto the stack, and push the browser Replace the

<span style="font-size: 14px;"></span>url<span style="font-size: 14px;"></span> in the address bar with the incoming <span style="font-size: 14px;"></span>url<span style="font-size: 14px;"></span> without refreshing the page (Just right!). <span style="font-size: 14px;"></span>

By the way, the difference is that

<span style="font-size: 14px;"></span>pushState<span style="font-size: 14px;"></span> will specify the <span style="font-size: 14px;"></span>url<span style="font-size: 14px;"></span> is pushed directly to the top of the history stack, while <span style="font-size: 14px;"></span>replaceState<span style="font-size: 14px;"></span> is to replace the top of the current history stack into the incoming data. <span style="font-size: 14px;"></span>

Both methods can help us meet the question setting conditions. In addition to subjective preference, which method to adopt must also be based on objective facts: lower version browsers have poor compatibility with the history API. For example, when encountering IE8, there seems to be no choice in the road ahead.

<span style="font-size: 14px;"></span>

How to track

<span style="font-size: 14px;"></span>url<span style="font-size: 14px;"></span>changes<span style="font-size: 14px;"></span>

on the browser side , tracking changes in form attributes generally uses an event listening mechanism, and tracking changes in

<span style="font-size: 14px;"></span>url<span style="font-size: 14px;"></span> is also unconventional.

对于<span style="font-size: 14px;">hash</span>方式的前端路由,通常可以监听 <span style="font-size: 14px;">hashchange</span> 事件,在事件回调中处理相应的页面视图展示等逻辑。

此外,HTML5提供的 <span style="font-size: 14px;">popstate</span> 事件也会在<span style="font-size: 14px;">url</span><span style="font-size: 14px;">hash</span>发生改变时触发。也就是说如果可以忽略低版本浏览器,我们使用<span style="font-size: 14px;">hash</span>方式路由时也可以采用监听这个事件进行回调处理。

那么,如果是采用history API的形式呢?根据MDN的描述:

调用 <span style="font-size: 14px;">history.pushState()</span> 或者 <span style="font-size: 14px;">history.replaceState()</span> 不会触发 <span style="font-size: 14px;">popstate</span> 事件。<span style="font-size: 14px;">popstate</span> 事件只会在浏览器某些行为下触发, 比如点击后退按钮(或者在JavaScript中调用 <span style="font-size: 14px;">history.back()</span> 方法)。

这也就是说,我们在使用history API改变浏览器的<span style="font-size: 14px;">url</span>时,仍需要额外的步骤去触发 <span style="font-size: 14px;">popstate</span> 事件,例如调用 <span style="font-size: 14px;">history.back()</span><span style="font-size: 14px;">history.forward()</span> 等方法。

从兼容性上来讲,前面有提及<span style="font-size: 14px;">hash</span>的方式兼容性更好。然而,对于低版本的浏览器,例如IE6等等,不支持 <span style="font-size: 14px;">hashchange</span> 事件。这个时候我们只能通过 <span style="font-size: 14px;">setInterval</span> 设置心跳的方式去模拟 <span style="font-size: 14px;">hashchange</span>

<span style="font-size: 14px;">var oldHash = location.hash;var oldURL = location.href;<br/><br/>setInterval(function() {    var newHash = location.hash;    var newURL = location.href;    if (newHash !== oldHash && typeof window.onhashchange === &#39;function&#39;) {        // 执行onhashchange回调<br/>        window.onhashchange({            &#39;type&#39;: &#39;hashchange&#39;,            &#39;oldURL&#39;: oldURL,            &#39;newURL&#39;: newURL<br/>        });<br/><br/>        oldHash = newHash;<br/>        oldURL = newURL;<br/>    }<br/>}, 100);<br/></span>

一个简单实现

这里,给出一个很简单的实现:

<span style="font-size: 14px;">router.js</span>

<span style="font-size: 14px;">function FrontRouter() {    this.routes = {};<br/>    window.addEventListener(&#39;load&#39;, this.resolve.bind(this), false);<br/>    window.addEventListener(&#39;hashchange&#39;, this.resolve.bind(this), false);<br/>}<br/><br/>FrontRouter.prototype.route = function(path, callback) {    this.routes[path] = callback || function() {};<br/>};<br/><br/>FrontRouter.prototype.resolve = function() {    this.curHash = location.hash.slice(1) || &#39;/&#39;;    typeof this.routes[this.curHash] === &#39;function&#39; && this.routes[this.curHash]();<br/>};<br/></span>

<span style="font-size: 14px;">index.html</span>

<span style="font-size: 14px;"><ul>    <li><a href=&#39;#blue&#39;></a></li>    <li><a href=&#39;#yellow&#39;></a></li>    <li><a href=&#39;#red&#39;></a></li></ul><br/></span>

<span style="font-size: 14px;">index.js</span>

<span style="font-size: 14px;">var router = new FrontRouter();<br/><br/>router.route(&#39;blue&#39;, function() {<br/>    document.body.style.backgroundColor = &#39;blue&#39;;<br/>});<br/><br/>router.route(&#39;yellow&#39;, function() {<br/>    document.body.style.backgroundColor = &#39;yellow&#39;;<br/>});<br/><br/>router.route(&#39;red&#39;, function() {<br/>    document.body.style.backgroundColor = &#39;red&#39;;<br/>});<br/></span>

一点总结

应用场景

前端路由大部分的应用场景,就是我们现在熟知的单页应用SPA。

不存在纯前端路由

我们此前所描述的前端路由,建立在已经打开了一个初始页面基础之上,然后在这个页面之内进行页面替换。然而,我们如何进入这个初始页面?仅靠前端路由肯定是力所不及。我们至少要向后端发送一次http请求,接收所需要加载的页面不是吗?

所以,我们并不能抛弃后端路由部分。这也意味着,我们需要和后端确认各自的分工,哪些url归前端解析,哪些归后台解析。

The above is the detailed content of What is front-end routing and its explanation. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn