摘要:服務器端路由對于服務器來說,當接收到客戶端發(fā)來的請求,會根據(jù)請求的,來找到相應的映射函數(shù),然后執(zhí)行該函數(shù),并將函數(shù)的返回值發(fā)送給客戶端??蛻舳寺酚蓪τ诳蛻舳送ǔ闉g覽器來說,路由的映射函數(shù)通常是進行一些的顯示和隱藏操作。
原文地址:http://syaning.com/2017/01/10...
?
理解Web路由 1.什么是路由在Web開發(fā)過程中,經(jīng)常會遇到『路由』的概念。那么,到底什么是路由?簡單來說,路由就是URL到函數(shù)的映射。
2.router和route的區(qū)別route就是一條路由,它將一個URL路徑和一個函數(shù)進行映射,例如:
/users -> getAllUsers() /users/count -> getUsersCount()
這就是兩條路由,當訪問/users的時候,會執(zhí)行g(shù)etAllUsers()函數(shù);當訪問/users/count的時候,會執(zhí)行g(shù)etUsersCount()函數(shù)。
而router可以理解為一個容器,或者說一種機制,它管理了一組route。簡單來說,route只是進行了URL和函數(shù)的映射,而在當接收到一個URL之后,去路由映射表中查找相應的函數(shù),這個過程是由router來處理的。一句話概括就是 “The router routes you to a route“。
3.服務器端路由對于服務器來說,當接收到客戶端發(fā)來的HTTP請求,會根據(jù)請求的URL,來找到相應的映射函數(shù),然后執(zhí)行該函數(shù),并將函數(shù)的返回值發(fā)送給客戶端。對于最簡單的靜態(tài)資源服務器,可以認為,所有URL的映射函數(shù)就是一個文件讀取操作。對于動態(tài)資源,映射函數(shù)可能是一個數(shù)據(jù)庫讀取操作,也可能是進行一些數(shù)據(jù)的處理,等等。
以Express為例,
app.get("/", (req, res) => { res.sendFile("index") }) app.get("/users", (req, res) => { db.queryAllUsers() .then(data => res.send(data)) })
這里定義了兩條路由:
當訪問/的時候,會返回index頁面
當訪問/users的時候,會從數(shù)據(jù)庫中取出所有用戶數(shù)據(jù)并返回
不僅僅是URL
在router匹配route的過程中,不僅會根據(jù)URL來匹配,還會根據(jù)請求的方法來看是否匹配。例如上面的例子,如果通過POST方法來訪問/users,就會找不到正確的路由。
4.客戶端路由對于客戶端(通常為瀏覽器)來說,路由的映射函數(shù)通常是進行一些DOM的顯示和隱藏操作。這樣,當訪問不同的路徑的時候,會顯示不同的頁面組件??蛻舳寺酚勺畛R姷挠幸韵聝煞N實現(xiàn)方案:
基于Hash
基于History API
(1) 基于Hash
我們知道,URL中#及其后面的部分為hash。例如:
const url = require("url") var a = url.parse("http://example.com/a/b/#/foo/bar") console.log(a.hash) // => #/foo/bar
hash僅僅是客戶端的一個狀態(tài),也就是說,當向服務器發(fā)請求的時候,hash部分并不會發(fā)過去。
通過監(jiān)聽window對象的hashChange事件,可以實現(xiàn)簡單的路由。例如:
window.onhashchange = function() { var hash = window.location.hash var path = hash.substring(1) switch (path) { case "/": showHome() break case "/users": showUsersList() break default: show404NotFound() } }
(2) 基于History API
通過HTML5 History API可以在不刷新頁面的情況下,直接改變當前URL。詳細用法可以參考:
Manipulating the browser history Using the HTML5 History API
我們可以通過監(jiān)聽window對象的popstate事件,來實現(xiàn)簡單的路由:
window.onpopstate = function() { var path = window.location.pathname switch (path) { case "/": showHome() break case "/users": showUsersList() break default: show404NotFound() } }
但是這種方法只能捕獲前進或后退事件,無法捕獲pushState和replaceState,一種最簡單的解決方法是替換pushState方法,例如:
var pushState = history.pushState history.pushState = function() { pushState.apply(history, arguments) // emit a event or just run a callback emitEventOrRunCallback() }
不過,最好的方法還是使用實現(xiàn)好的history庫。
(3) 兩種實現(xiàn)的比較
總的來說,基于Hash的路由,兼容性更好;基于History API的路由,更加直觀和正式。
但是,有一點很大的區(qū)別是,基于Hash的路由不需要對服務器做改動,基于History API的路由需要對服務器做一些改造。下面來詳細分析。
假設服務器只有如下文件(script.js被index.html所引用):
/- |- index.html |- script.js
基于Hash的路徑有:
http://example.com/ http://example.com/#/foobar
基于History API的路徑有:
http://example.com/ http://example.com/foobar
當直接訪問 http://example.com/ 的時候,兩者的行為是一致的,都是返回了index.html文件。
當從http://example.com/跳轉(zhuǎn)到http://example.com/#/foobar或者http://example.com/foobar的時候,也都是正常的,因為此時已經(jīng)加載了頁面以及腳本文件,所以路由跳轉(zhuǎn)正常。
當直接訪問http://example.com/#/foobar的時候,實際上向服務器發(fā)起的請求是http://example.com/,因此會首先加載頁面及腳本文件,接下來腳本執(zhí)行路由跳轉(zhuǎn),一切正常。
當直接訪問http://example.com/foobar的時候,實際上向服務器發(fā)起的請求也是http://example.com/foobar,然而服務器端只能匹配/而無法匹配/foobar,因此會出現(xiàn)404錯誤。
因此如果使用了基于History API的路由,需要改造服務器端,使得訪問/foobar的時候也能返回index.html文件,這樣當瀏覽器加載了頁面及腳本之后,就能進行路由跳轉(zhuǎn)了。
5.動態(tài)路由上面提到的例子都是靜態(tài)路由,也就是說,路徑都是固定的。但是有時候我們需要在路徑中傳入?yún)?shù),例如獲取某個用戶的信息,我們不可能為每個用戶創(chuàng)建一條路由,而是在通過捕獲路徑中的參數(shù)(例如用戶id)來實現(xiàn)。
例如在Express中:
app.get("/user/:id", (req, res, next) => { // ... ... })
在Flask中:
@app.route("/user/6.嚴格路由") def get_user_info(user_id): pass
在很多情況下,會遇到/foobar和/foobar/的情況,它們看起來非常類似,然而實際上有所區(qū)別,具體的行為也是視服務器設置而定。
在Flask的文檔中,提到,末尾有斜線的路徑,類比于文件系統(tǒng)的一個目錄;末尾沒有斜線的路徑,類比于一個文件。因此訪問/foobar的時候,可能會重定向到/foobar/,而反過來則不會。
如果使用的是Express,默認這兩者是一樣的,也可以通過app.set來設置strict routing,來區(qū)別對待這兩種情況。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81283.html
摘要:基礎安裝路由功能作用,使用定義組件與路由的映射。定義渲染組件的位置。作用定義注意動態(tài)路由的動態(tài)部分改變時原來的組件會被復用,這樣就不會觸發(fā)生命周期鉤子函數(shù)。嵌套路由命名視圖命名路由別名重定向?qū)⒃O置為組件屬性命名路由就是給路由起個名字。 vue-router 基礎 install CDN
摘要:流行的今天不少同學會把前端路由跟后端路由弄混莫名其妙的怎么頁面啦之類奇怪的問題其實這就是沒弄清楚前端路由和后端路由的原因當然你用當我沒說本文所有前端路由都是的情況下不存在后端渲染好變量的情況原理首先我們看看前后端路由在瀏覽器中是怎么工作的上 spa流行的今天不少同學會把前端路由跟后端路由弄混, 莫名其妙的怎么頁面404啦之類奇怪的問題, 其實這就是沒弄清楚前端路由和后端路由的原因(當然...
摘要:在這里說明這些僅是個人理解,僅供參考最近做了一個項目,在這個項目中用到了路由,這是我首次接觸路由,感覺這是前端開發(fā)中必須要了解的一個插件。使用使用也是相當簡單,主要是和的配合,樣式在這里不多說,根據(jù)自己的頁面需求設計頁面即可。 ## 在這里說明這些僅是個人理解,僅供參考 ## 最近做了一個項目,在這個項目中用到了路由,這是我首次接觸路由,感覺這是前端開發(fā)中必須要了解的一個插件。該插件是...
閱讀 2432·2023-04-26 00:46
閱讀 593·2023-04-25 21:36
閱讀 737·2021-11-24 10:19
閱讀 2282·2021-11-23 09:51
閱讀 1028·2021-10-21 09:39
閱讀 841·2021-09-22 10:02
閱讀 1677·2021-09-03 10:29
閱讀 2707·2019-08-30 15:53