①之前我们有这么一段代码:
app.use('/', routes); //假如是根目录,那么交给routes.js来处理; app.use('/users', users); //假如是/users目录,交给users.js来处理
当访问根目录的时候,调用routes;当访问的是users路径是,由users来处理;
然后又知道,当访问其他路径时,会这么处理:
app.use(express.static(path.join(__dirname, 'public')));
即去查看public文件夹下有没有对应的静态页面,如果有,则显示。
那么假如以上都不符合呢?那么会报错。
显然,我们会有这样一种需求,假如当访问/test这样一个路径时,我们需要对她进行一次特殊的处理,例如发送访问时间给用户。
教程上是这么写的:
app.use('/test',routes.test); //假如访问的路径是test,那么行为方式是调用routes(即index.js)的test方法
但实际上,最近版本情况下,我们的index.js文件是这样的。
router.get('/', function (req, res, next) { //req是请求,res是回应 res.render('index', {title: 'Express'}); //回应调用render方法 });
显然,并没有这样一个方法。(教程上老版本的是这样的:index = router.get(略))
因此我们可以这么做,直接不对app.js做任何操作,但是在index.js添加这样一段代码
router.get('/test', function (req, res, next) { res.send('Hello, your visit time is ' + new Date() + '.'); })
然后重启路由,我们访问/test路径时,就会显示:
Hello, your visit time is Sun Jun 26 2016 15:38:49 GMT+0800 (中国标准时间).
但必须明白这个机制是什么。
②路由的机制:
错误的认识:
当我们按上面的写法来写的时候,就可能会产生一个错觉:
当访问/test时,由于index.js里面有
router.get('/test',
这样一段代码,无论把这段代码放在哪里,都会交给这段代码来处理访问/test这个路径。例如把这段代码放在users.js里,然后访问http://127.0.0.1/test,也可以获得这样的回应。
当然,事实上并非这样。
正确的认识:
事实上是这么做的,当访问根目录时,即http://127.0.0.1,然后他会去查看routes下(即index.js文件)有有没有这样一段代码:
router.get('/'
如果有,则调用其回调函数来进行处理。
如果没有,那么他会返回错误提示。(可能是404页面,也可能是其他错误提示)。
这里的/,指的是app.js中,基础路径:
app.use('/', routes);
的根路径。
具体举例的话:
假如我们有一个页面是A页面,我们计划其路径为/base/pageA
【方法一】我们可以这么做:
在app.js中,加入代码:
app.use('/', routes);
注意,这里的routes指向的是index.js
然后在index.js里加入代码:
router.get('/base/pageA', function (req, res, next) { res.send('Hello, your visit time is ' + new Date() + '.'); })
我们便可以通过http://127.0.0.1/base/pageA来访问到我们需要访问的网页了
【方法二】
我们也可以这么做:
app.js里添加代码
var base = require('./routes/base'); //routes文件夹下的base文件
和
app.use('/base', base);
然后在routes文件夹下新建base.js文件,输入以下代码:
var express = require('express'); //调用express模块 var router = express.Router(); //调用模块的Router方法 /* GET home page. */ router.get('/pageA', function (req, res, next) { res.send('Hello, in another page, your visit time is ' + new Date() + '.'); }) module.exports = router;
此时访问网页,将会显示:
Hello, in another page, your visit time is Sun Jun 26 201617:08:52 GMT+0800 (中国标准时间).
解释:
我是这么解释的,在app.js里,use函数的第一个参数,其路径表示的是基础路径,而在第二个参数里,js文件的路径是相对路径(相对于这个基础路径的路径)。
假如基础路径是“/app”,
那么相对路径是“/”时,其路径指/app/;
而相对路径是“/test”时,其路径指/app/test;
相对路径是“/index/pageA”时,其路径指/app/index/pageA
注意,根据我测试,似乎不能使用“../test”来访问/test这样的路径
假如路径冲突会如何?
即上面的方法一和方法二同时使用,那么访问http://127.0.0.1/base/pageA的结果是什么?
实践证明,根据app.js来定
由于在app.js里,路由是有先后顺序的,因此哪个在前,就会先交给谁处理。
例如:
app.use('/', routes); //假如是根目录,那么交给routes.js来处理; app.use('/base', base);
是index.js相应的代码进行处理;
而
app.use('/base', base); app.use('/', routes);
这样的顺序,是由base.js相应的代码进行处理。
③路径匹配:
假如用户访问一个这样的路径:
/base/myname
其中,myname是用户名,他可能是'abc',也可能是'defg'等(不含引号)。
那么,我们可能就需要获取这个myname。
之前我们遇见的一般是这样的情况:
/base?name=abc
我们可以通过url模块的pathname方法来确定其name属性值。
但当前需求显然和之前不同。因此我们使用另外一个方法,在base.js添加以下代码。
router.get('/:username', function (req, res, next) { res.send('username: ' + req.params.username); })
通过这样的方式,来将myname位置的值,赋值给req的username属性
例如,我们访问:http://127.0.0.1/base/page(注意,避免有直接对该链接进行处理的代码)
会返回我们这样的内容:
username: page
根据解释,:username这样的形式,会被自动编译为正则表达式,类似:\/user\/([^\/]+)\/? 这样的形式,而其参数可以在响应函数中通过req.params属性来访问。
另外,路径同样支持javascript的【正则表达式】。因此可以匹配更加复杂的路径,但由于是匿名参数,因此需要通过req.params[0]、req.params[1]来访问了。