Was ist Front-End-Routing?
Das sogenannte Front-End-Routing bietet die Möglichkeit, dass der Client-Browser verschiedene Ansichtsseiten basierend auf unterschiedlichen URLs rendern kann, ohne auf den Server angewiesen zu sein.
Die Rationalität der Existenz von Front-End-Routing
Wenn das Schwert von Ajax noch nicht enthüllt wurde, das Front-End jedoch schon Noch in den Kinderschuhen steckt das Routing. Die Arbeit wird an das Backend übergeben. Beim Seitenwechsel sendet der Browser verschiedene <code><span style="font-size: 14px;">url</span>
URL-Anfragen. Wenn der Server die Anfrage des Browsers empfängt, analysiert er die verschiedenen <code><span style="font-size: 14px;">url</span> <code><span style="font-size: 14px;">url</span><span style="font-size: 14px;">html</span>
, um das erforderliche HTML
oder die Vorlage zu verbinden und das Ergebnis dann an das Browser-Rendering auf dem zurückzugeben serverseitig.
Serverseitiges Routing ist ebenfalls unkonventionell und hat Vor- und Nachteile. Sein Vorteil ist eine höhere Sicherheit und eine strengere Kontrolle über die Seitenanzeige. Dies ist in bestimmten Szenarien nützlich, beispielsweise bei einem Bestellzahlungsprozess, bei dem jeder Schritt erst erreicht werden kann, nachdem der vorherige Schritt erfolgreich ausgeführt wurde. Dadurch kann jedem Schritt des Prozesses auf der Serverseite ein Überprüfungsmechanismus hinzugefügt werden, und nur die richtige Seite wird zurückgegeben, wenn die Überprüfung bestanden wird. Das Front-End-Routing kann also nicht bei jedem Schritt eine Überprüfung durchführen? Natürlich nicht, ich glaube, dass Ihr Code sehr streng geschrieben werden kann, um sicherzustellen, dass der Prozess unter normalen Umständen nicht schief geht, aber eine weitere Tatsache, der man sich stellen muss, ist: Das Frontend verfügt überhaupt über keine Sicherheit. Benutzer können den Code nach Belieben ändern, um verschiedene Prozesse einzugeben, und Sie können hierfür viel Verarbeitungslogik hinzufügen. Im Vergleich dazu sind die Zugriffsberechtigungen auf die Back-End-Kontrollseite natürlich sicherer und einfacher. <span style="font-size: 14px;">reload</span>
Andererseits erhöht Back-End-Routing zweifellos die Belastung auf der Serverseite und erfordert ein
Seite, Die Benutzererfahrung ist eigentlich nicht gut.
Auf diese Weise kommt das Front-End-Routing ins Spiel. Erstens verringert sein Aufkommen zweifellos den Druck auf der Serverseite. Insbesondere bei einer komplexeren Anwendung, oder genauer gesagt bei einer Anwendung mit einem komplexen Routing-System, muss der Server für jede unterschiedliche URL einen Teil der Verarbeitungslogik ausführen, was in Situationen mit hoher Parallelität etwas unerträglich ist Beim Seitenwechsel muss nicht die gesamte Seite aktualisiert werden. Es gibt keine Netzwerkverzögerung und keine flackernde Aktualisierung, was das Benutzererlebnis verbessert.
Front-End-Routing-Implementierungsmethode
- Nachdem das Ziel erreicht ist, welche Probleme müssen wir lösen? Wir können das Problem ein wenig aufschlüsseln, zuerst einen kleinen Plan von 100 Millionen erstellen und dann mit dem nächsten Schritt fortfahren, nachdem wir es erkannt haben:)
<code><span style="font-size: 14px;">url</span> Unter der Voraussetzung, dass die Seite nicht aktualisiert wird, implementieren Sie
URL -
Änderung<code><span style="font-size: 14px;">url</span>
Erfassung
, um die Seitenersetzungslogik durchzuführen<code><span style="font-size: 14px;">url</span>
Wie man es implementiert aktualisierenURL<code><span style="font-size: 14px;">url</span>und die Seite wird nicht aktualisiert
Wie bereits erwähnt, ist eines der Merkmale von Front- Das End-Routing im Vergleich zum Back-End-Routing besteht darin, dass die Seite nicht vollständig aktualisiert wird. Wechseln Sie die Ansicht unter den gegebenen Umständen. Die Seite <code><span style="font-size: 14px;">value</span>
URL hat sich geändert, wurde aber nicht neu geladen! Es mag etwas seltsam erscheinen, aber eigentlich ist es keine große Sache. <code><span style="font-size: 14px;">url</span>
Wert
des Eingabefelds zu ändern Lösen Sie jedoch nicht den Vorgang zum Anfordern der Seite aus, damit die neue Seite nicht neu geladen wird. Wenn das Ändern des Werts des Eingabefelds und das Senden der Anfrage eine atomare Operation wären, wären wir hilflos. Glücklicherweise wird die Anfrage erst gesendet, wenn wir die Eingabetaste drücken (das ist offensichtlich). Daher werden dadurch Bedingungen geschaffen, die es uns ermöglichen, den Wert der Adressleiste zu ändern, ohne eine Seitenaktualisierungsanforderung auszulösen. Bietet BOM eine Methode zum Ändern der Browser-Adressleiste URL
, ohne einen Anforderungsvorgang auszulösen? Hier gibt es zwei Möglichkeiten, den Bedarf zu decken. Die erste besteht darin, das Feld <code><span style="font-size: 14px;">url</span>
Hash in der <span style="font-size: 14px;">hash</span>
<span style="font-size: 14px;">URL</span>
zu verwenden Zweitens ist die von HTML5 bereitgestellte History API
<span style="font-size: 14px;">hash</span>
Hash
Weg<span style="font-size: 14px;">http</span>
Verstehen<code><span style="font-size: 14px;">url</span>
http Das Protokoll erkennt, dass <span style="font-size: 14px;">#</span>
<span style="font-size: 14px;">URL</span>
<span style="font-size: 14px;">#</span>
<span style="font-size: 14px;">http://www.gmail.com/text/#123</span>
gekennzeichnet ist. <span style="font-size: 14px;">123</span>
Zum Beispiel: <code><span style="font-size: 14px;">url</span>
http://www.gmail.com/text/#123, <span style="font-size: 14px;">hash</span>
<span style="font-size: 14px;">123</span>
<code>URL<code><span style="font-size: 14px;">location.hash</span>
>hash<code><span style="font-size: 14px;">url</span> Teil. <span style="font-size: 14px;">hash</span>
Öffnen Sie die Konsole und geben Sie <code><span style="font-size: 14px;">url</span>
location.hash ein, Sie können den aktuellen <span style="font-size: 14px;">hash</span>
Der <span style="font-size: 14px;"><code>
Hash<span style="font-size: 14px;">location.hash = '123'</span>
-Teil der URL<code><span style="font-size: 14px;">url</span> (wenn der aktuelle <code><span style="font-size: 14px;">#123</span>
url existiert nicht
<h3>Hash<span style="font-size: 14px;"></span>
</h3>
gibt einen leeren String zurück). Geben Sie als Nächstes <p>location.hash = '123'<span style="font-size: 14px;"></span></p>
ein. Sie finden <span style="font-size: 14px;">history</span>
<span style="font-size: 14px;">URL</span>
hat sich geändert und das Feld <span style="font-size: 14px;">window.history</span>
<code><span style="font-size: 14px;">#123</span> wurde am Ende hinzugefügt und die Seite wurde nicht aktualisiert. Offensichtlich entspricht dies unseren Anforderungen. <span style="font-size: 14px;">pushState</span>
Verlaufs-API<span style="font-size: 14px;">replaceState</span>
HTML5 führt einen
<span style="font-size: 14px;">history.replaceState(dataObj, title, url);<br/>history.pushState(dataObj, title, url);<br/></span>
ein Das Objekt enthält eine Reihe von APIs für den Zugriff auf den Browserverlauf, auf die über window.history<code><span style="font-size: 14px;">url</span> zugegriffen werden kann. <code><span style="font-size: 14px;">url</span>Hier interessieren uns die beiden API-Methoden:
<blockquote>pushState<p>
und <span style="font-size: 14px;">pushState</span>
replaceState
. <code><span style="font-size: 14px;">url</span><span style="font-size: 14px;">replaceState</span>
Wie oben gezeigt, erhalten sie genau die gleichen Parameter, beide bearbeiten den Verlaufsstapel des Browsers, verschieben die übergebene URL und die zugehörigen Daten auf den Stapel und ersetzen das </p>url</blockquote>
in der Browser-Adressleiste mit der eingehenden </span>url</p>
Und ohne die zu aktualisieren Seite (genau richtig!). <code><span style="font-size: 14px;">url</span>Der Unterschied besteht übrigens darin, dass
<p>pushState<span style="font-size: 14px;">
das <code><span style="font-size: 14px;">url</span>< angibt code><span style="font-size: 14px;">url</span>
<🎜>replaceState<🎜>
<🎜> dazu dient Ersetzen Sie den aktuellen Verlaufsdatensatz. Der obere Teil des Stapels wird durch die eingehenden Daten ersetzt. <🎜><🎜><🎜><🎜><🎜>Beide Methoden können uns helfen, die Bedingungen für die Fragestellung zu erfüllen. Neben der subjektiven Präferenz muss die zu verwendende Methode auch auf objektiven Fakten basieren: Browser niedrigerer Versionen sind schlecht mit der Verlaufs-API kompatibel. Wenn Sie beispielsweise auf IE8 stoßen, scheint es auf dem weiteren Weg keine Wahl zu geben. <🎜><🎜><🎜><🎜>So verfolgen Sie <🎜><🎜>URL<🎜>
<🎜>Änderungen<🎜><🎜><🎜><🎜> im Browser Auf der Clientseite werden im Allgemeinen Ereignisüberwachungsmechanismen verwendet, um Änderungen in Formularattributen zu verfolgen, und die Verfolgung von Änderungen in <🎜><🎜>URL<🎜>
<🎜> ist ebenfalls unkonventionell. <🎜><🎜>对于<span style="font-size: 14px;">hash</span>
方式的前端路由,通常可以监听 <span style="font-size: 14px;">hashchange</span>
事件,在事件回调中处理相应的页面视图展示等逻辑。
此外,HTML5提供的 <span style="font-size: 14px;">popstate</span>
事件也会在<code><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改变浏览器的<code><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 === 'function') { // 执行onhashchange回调<br/> window.onhashchange({ 'type': 'hashchange', 'oldURL': oldURL, 'newURL': 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('load', this.resolve.bind(this), false);<br/> window.addEventListener('hashchange', 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) || '/'; typeof this.routes[this.curHash] === 'function' && this.routes[this.curHash]();<br/>};<br/></span>
<span style="font-size: 14px;">index.html</span>
<span style="font-size: 14px;"><ul> <li><a href='#blue'></a></li> <li><a href='#yellow'></a></li> <li><a href='#red'></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('blue', function() {<br/> document.body.style.backgroundColor = 'blue';<br/>});<br/><br/>router.route('yellow', function() {<br/> document.body.style.backgroundColor = 'yellow';<br/>});<br/><br/>router.route('red', function() {<br/> document.body.style.backgroundColor = 'red';<br/>});<br/></span>
一点总结
应用场景
前端路由大部分的应用场景,就是我们现在熟知的单页应用SPA。
不存在纯前端路由
我们此前所描述的前端路由,建立在已经打开了一个初始页面基础之上,然后在这个页面之内进行页面替换。然而,我们如何进入这个初始页面?仅靠前端路由肯定是力所不及。我们至少要向后端发送一次http请求,接收所需要加载的页面不是吗?
所以,我们并不能抛弃后端路由部分。这也意味着,我们需要和后端确认各自的分工,哪些url归前端解析,哪些归后台解析。