web开发中路由route和路由器router到底是什么
原文链接:点击打开链接
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.hashvar path = hash.substring(1)switch (path) {case '/':showHome()breakcase '/users':showUsersList()breakdefault: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.pathnameswitch (path) {case '/':showHome()breakcase '/users':showUsersList()breakdefault:show404NotFound()}
}
但是这种方法只能捕获前进或后退事件,无法捕获pushState和replaceState,一种最简单的解决方法是替换pushState方法,例如:
var pushState = history.pushState
history.pushState = function() {pushState.apply(history, arguments)// emit a event or just run a callbackemitEventOrRunCallback()
}
不过,最好的方法还是使用实现好的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开发中路由route和路由器router到底是什么相关推荐
- 对Django Web开发中路由(ulr)配置 '^static/(?Plt;pathgt;.*)' 的理解
在Django静态文件管理中,开发过程中需要启用静态文件服务,在settings.py文件的INSTALLED_APPS中,启用静态文件管理模块'django.contrib.staticfiles' ...
- Web开发中的路由是什么意思?(关键词:Web开发/路由)
路由就是URL到函数的映射. 在web开发中,"route"是指根据url, 分配到对应的处理程序. 路由: 就是一个路径的解析,根据客户端提交的路径,将请求解析到相应的控制器上: ...
- Vue中路由管理器Vue Router使用介绍(三)
2019独角兽企业重金招聘Python工程师标准>>> 一.路由定义添加动态参数定义 1.路由定义项,使用:xx 方式 定义动态参数 {path:'/user/:id/:name', ...
- 【笔记-node】《imooc-nodejs入门到企业web开发中的应用》
目录 课程名 备注 入门必学 nodejs入门到企业web开发中的应用 框架与工具 node.js+koa2+mysql打造前后端分离精品项目<旧岛> 项目实战 20190317-2020 ...
- 038——VUE中组件之WEB开发中组件使用场景与定义组件的方式
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...
- 谈谈WEB开发中的苦大难字符集问题
记得刚做javaweb开发的时候被这个编码问题搞得晕头转向,经常稀里糊涂的编码正常了一会编码又乱了.那个时候迫于项目进度大多都是知其然不知其所以然.后来有时间就把整个体系搞了个遍,终于摸通了来龙去脉. ...
- Web开发中的相对路径和绝对路径
在学习HTML的时候一定会遇到引入文件和链接跳转页面,比如:JS文件.CSS文件.Image图片.我们就会考虑是相对路径和绝对路径的问题.下面PHP程序员雷雪松就详细讲解下Web开发中的相对路径和绝对 ...
- web开发中目录路径问题的解决
web开发中目录路径问题的解决 参考文章: (1)web开发中目录路径问题的解决 (2)https://www.cnblogs.com/freeweb/p/4751403.html 备忘一下.
- java sessionstate_在Java Web开发中自定义Session
Session在存储安全性要求较高的会话信息方面是必不可少的,对于分布式Web应用自定义Session支持独立的状态服务器或集群是必须的.本文就来教大家如何在Java Web开发中自定义Session ...
最新文章
- Python监控目录文件夹,并使用SFTP上传目录及文件到linux服务器
- 设计新Xlator扩展GlusterFS[转]
- php过滤第一个逗号和最后一个逗号,PHP字符过滤函数去除字符串最后一个逗号(rtrim)...
- QT学习:Qt操作数据库
- 评估创业项目的十大标准
- Unit9 Mangement Strategies—— I
- 设置Eclipse中的字符集为UTF-8
- java monitor 翻译_管程(Monitor)概念及Java的实现原理
- ROS学习笔记(八): ROS通信架构
- python是什么意思中文-python是什么意思中文
- k2698场效应管参数电流_值得一观!场效应管 VS 三极管
- 【Java】---JVM内存模型
- 史上最全SpringCloud2.0视频教程
- 西门子S7-200smart型PLC使用profinet通讯控制G120变频器程序
- 2020年G3锅炉水处理证模拟考试题库及G3锅炉水处理理论考试试题
- nas918+支持的cpu_C2000浮点运算注意事项——CPU和CLA的差异及误差处理技巧
- 同一台电脑安装两个版本的jdk和jre
- 开关造成的毛刺_令人困扰的DAC输出毛刺消灭记
- mysql 表名 复数_数据库表名,应该用复数还是单数
- 多测师肖sir_高级讲师_第2个月第33讲解jenkins