[转] 理解Web路由
1. 什么是路由
在Web开发过程中,经常会遇到『路由』的概念。那么,到底什么是路由?简单来说,路由就是URL到函数的映射。
2. router和route的区别
route就是一条路由,它将一个URL路径和一个函数进行映射,例如:
/users -> getAllUsers()
/users/count -> getUsersCount()
这就是两条路由,当访问/users的时候,会执行getAllUsers()函数;当访问/users/count的时候,会执行getUsersCount()函数。
而router可以理解为一个容器,或者说一种机制,它管理了一组route。简单来说,route只是进行了URL和函数的映射,而在当接收到一个URL之后,去路由映射表中查找相应的函数,这个过程是由router来处理的。一句话概括就是 “The router routes you to a route”。
3. 服务器端路由
对于服务器来说,当接收到客户端发来的HTTP请求,会根据请求的URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,可以认为,所有URL的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理,等等。
以Express为例,
app.get('/', (req, res) => {
res.sendFile('index')
})
app.get('/users', (req, res) => {
db.queryAllUsers()
.then(data => res.send(data))
})
这里定义了两条路由:
- 当访问/的时候,会返回index页面
- 当访问/users的时候,会从数据库中取出所有用户数据并返回
不仅仅是URL
在router匹配route的过程中,不仅会根据URL来匹配,还会根据请求的方法来看是否匹配。例如上面的例子,如果通过POST方法来访问/users,就会找不到正确的路由。
4. 客户端路由
对于客户端(通常为浏览器)来说,路由的映射函数通常是进行一些DOM的显示和隐藏操作。这样,当访问不同的路径的时候,会显示不同的页面组件。客户端路由最常见的有以下两种实现方案:
- 基于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仅仅是客户端的一个状态,也就是说,当向服务器发请求的时候,hash部分并不会发过去。
通过监听window对象的hashChange事件,可以实现简单的路由。例如:
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
我们可以通过监听window对象的popstate事件,来实现简单的路由:
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()
}
不过,最好的方法还是使用实现好的history库。
(3) 两种实现的比较
总的来说,基于Hash的路由,兼容性更好;基于History API的路由,更加直观和正式。
但是,有一点很大的区别是,基于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/跳转到http://example.com/#/foobar或者http://example.com/foobar的时候,也都是正常的,因为此时已经加载了页面以及脚本文件,所以路由跳转正常。
当直接访问http://example.com/#/foobar的时候,实际上向服务器发起的请求是http://example.com/,因此会首先加载页面及脚本文件,接下来脚本执行路由跳转,一切正常。
当直接访问http://example.com/foobar的时候,实际上向服务器发起的请求也是http://example.com/foobar,然而服务器端只能匹配/而无法匹配/foobar,因此会出现404错误。
因此如果使用了基于History API的路由,需要改造服务器端,使得访问/foobar的时候也能返回index.html文件,这样当浏览器加载了页面及脚本之后,就能进行路由跳转了。
5. 动态路由
上面提到的例子都是静态路由,也就是说,路径都是固定的。但是有时候我们需要在路径中传入参数,例如获取某个用户的信息,我们不可能为每个用户创建一条路由,而是在通过捕获路径中的参数(例如用户id)来实现。
例如在Express中:
app.get('/user/:id', (req, res, next) => {
// ... ...
})
在Flask中:
@app.route('/user/<user_id>')
def get_user_info(user_id):
pass
6. 严格路由
在很多情况下,会遇到/foobar和/foobar/的情况,它们看起来非常类似,然而实际上有所区别,具体的行为也是视服务器设置而定。
在Flask的文档中,提到,末尾有斜线的路径,类比于文件系统的一个目录;末尾没有斜线的路径,类比于一个文件。因此访问/foobar的时候,可能会重定向到/foobar/,而反过来则不会。
如果使用的是Express,默认这两者是一样的,也可以通过app.set来设置strict routing,来区别对待这两种情况。
[转] 理解Web路由的更多相关文章
- 理解Web路由(浅谈前后端路由与前后端渲染)
1.什么是路由? 在Web开发过程中,经常会遇到『路由』的概念.那么,到底什么是路由?简单来说,路由就是URL到函数的映射. 路由的概念最开始是由后端提出来的,在以前用模板引擎开发页面的时候,是使用路 ...
- AngularJS进阶(一)深入理解ANGULARUI路由_UI-ROUTER
深入理解ANGULARUI路由_UI-ROUTER 最近在用 ionic写个webapp 看到几个demo中路由有好几种,搞的有点晕,查下资料研究下,做个笔记,其中大部分为摘抄别人的,做个说明免得被人 ...
- 深入理解 web 协议(一)- http 包体传输
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/WlT8070LlrnSODFRDwZsUQ作者:吴越 开坑这个系列的原因,主要是在大前端学习的 ...
- 从文件下载视角来理解Web API
一.问题源起 从Web From过来的人应该会比较熟悉以下下载文件的代码: [HttpPost] [Route("Download")] public void Download( ...
- 深入理解Web标准(网站标准)
深入理解Web标准(网站标准) 我觉得一名Web前端应该好好理解Web标准到底是什么,为什么要在我们的实际实践中遵循Web标准. 什么是Web标准.百度百科的解释是: WEB标准不是某一个标准,而 ...
- 理解Web标准(网站标准)
我觉得一名Web前端应该好好理解Web标准到底是什么,为什么要在我们的实际实践中遵循Web标准. 什么是Web标准.百度百科的解释是: WEB标准不是某一个标准,而是一系列标准的集合.网页主要由三部分 ...
- HTML与CSS入门——第一章 理解Web的工作方式
知识点: 1.万维网的简史 2."网页"的含义,以及该术语不能反映所涉及的所有内容的原因 3.如何从你的个人计算机进入别人的浏览器 4.选择Web托管提供商的方法 5.不同的Web ...
- 快速理解web语义化
什么是Web语义化 Web语义化是指使用恰当语义的html标签.class类名等内容,让页面具有良好的结构与含义,从而让人和机器都能快速理解网页内容.语义化的web页面一方面可以让机器在更少的人类干预 ...
- 理解Web应用程序的代码结构和运行原理(3)
1.理解Web应用程序的运行原理和机制 Web应用程序是基于浏览器/服务器模式(也称B/S架构)的应用程序,它开发完成后,需要部署到Web服务器上才能正常运行,与用户交互的客户端是网页浏览器. 浏览器 ...
随机推荐
- Linux 命令详解(十)Shell脚本的数组详解
1.数组定义 [root@bastion-IDC ~]# a=( ) [root@bastion-IDC ~]# echo $a 一对括号表示是数组,数组元素用“空格”符号分割开. 2.数组读取与赋值 ...
- 使用JS监听键盘按下事件(keydown event)
1.监听全局键盘按下事件,例如监听全局回车事件 1 $(document).keydown(function(event){ 2 if(event.keyCode == 13){ 3 alert('你 ...
- buildroot构建项目(四)--- u-boot 2017.11 适配开发板修改 2 ---- 系统启动初始化之一
一.代码分析 上一节已经分析了链接文件,知道了首先代码是从 _start 开始,之后设置了中断向量表,然后从 start.s 开始运行. _start:vectors.S (arch\arm\lib) ...
- WinRar 压缩接压缩文件
windows WinRAR 定时压缩文件 命名当天时间 设置时间格式: set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%" 指定 WinRAR ...
- JavaScript之不规则Table转化为可定点索引td节点的网格矩阵【插件】
由于解析课程表的缘故,有如下需求: 1. 将任意表格解析成独立的单元格矩阵[本次博文的缘由] 2. 根据矩阵坐标,确定任意一格的节点 /* 表格-->网格化 标记表格的位置及其对应的节点 * ...
- HTML链接/实施CSS的三种方法
①页面内部链接: <head> <style type="text/css"> /*Cascading Style Shee ...
- JavaScript之浏览器兼容问题与IE(神经病一样的浏览器)
IE是最讨厌的浏览器,没有之一.----题记 废话不说,粘上大图~
- HTML5 CSS JavaScript在网页中扮演的角色
HTML (content layer) CSS (presentation layer) JavaScript (Interactive layer) 参考链接: [1] https://www.y ...
- C#实现office文档转换为PDF格式
1.安装组件OfficeSaveAsPDFandXPS 需要安装office 2007 还有一个office2007的插件OfficeSaveAsPDFandXPS 下载地址 OfficeSave ...
- C - Portals Gym - 102006C (网络流最小割)
题目链接:https://cn.vjudge.net/contest/283918#problem/C 题目大意:T个测试数据,然后给你一个字符串,每一个字符串包括‘s’,‘t’,‘o’,‘#’,‘. ...