# 一、工作原理

当访问http://localhost:3000, 浏览器会向服务器发送请求,包括请求的方法、路径、HTTP协议版本和请求头信息。app会解析请求的路径,调用相应的逻辑,route/index.js中有 router.get('/',function(){})通过res.render('index',{title:"cky"})调用视图模板index,传递title变量,最终生成HTML页面,返回给浏览器。 浏览器收到内容后,通过分析需要获取/stylesheet/style.css,因此会再次向服务器发起请求,app.js并没有一个路由指派到/stylesheets/style.css,但app通过app.use(express.static(__dirname+'/public'))配置了静态文件服务器,因此会定向到app.js所在目录下的/public/stylesheets/style.css拿取这个文件。

这是一个典型的MVC架构,浏览器发送请求,由路由控制接收,根据不同的路径定向到不同的服务器,控制器处理用户具体的请求,可能会访问数据库中的对象,即模型部分,生成视图的HTML,最后再由控制器返回给浏览器,完成一次请求。

# 二、创建路由规则

当我们在浏览器访问http://localhost:3000/cky 的时候,服务器响应头返回404 NOT FOUND的错误,这是因为/cky是一个不存在的路由规则,而且它也不是一个public目录下的文件,所以响应404。 假设我们创建一个/cky的路由规则

router.get('/cky', function(req, res, next) {
  res.send("cky route");
});

1
2
3
4

即可访问。 服务器开始监听之前,设置好了所有的路由规则,当请求到来时直接分配到相应的函数,app.get是路由规则创建函数。

# 三、路径匹配

上面讲到了为固定的路径设置路由规则,Express还提供了更高级的路径匹配模式。 1.

router.get('/user/:username',function(req,res){
    res.send('user:' +req.params.username);
});
1
2
3

访问结果: 路径规则/user/username会自动编译成正则表达式,类似于/user/([^/]+)/?这样的形式,路径参数可以在相应函数中通过req.params的属性访问。

  1. 路径规则同样支持javascript正则表达式,例如router.get(\/user\/([^\/]+)\/?,callback)这样的好处在于可以定义更加复杂的路径规则,不同之处是配置的参数是匿名的,因此需要通过req.params[0]这样的形式访问。

# 四、REST风格的路由规则

Express支持REST风格的请求方式,REST意思是表征状态转移,它是一种基于HTTP协议的网络应用的接口风格,充分利用HTTP的方法实现了统一风格的接口服务,HTTP协议定义了以下8个标准方法:

请求方法 用途
GET 请求获取的资源 获取
POST 向指定资源提交数据 新增
DELETE 请求服务器删除指定资源 删除
PUT 请求服务器存储一个资源 更新
HEAD 请求指定资源的响应头
TRACE 回显服务器数到的请求,主要用户测试或诊断
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 返回服务器支持HTTP请求方法

Express对每种HTTP请求方法都设计了不同的路由绑定函数

  • GET : app.get(path,callback);
  • POST: app.post(path,callback);
  • PUT : app.put(path,callback);
  • DELETE: app.delete(path,callback); ... ... 所有方法 app.all(path,callback); app.all函数,它支持把所有的请求方法绑定到同一个相应函数,是一个非常灵活的函数。

# 五、控制权转移

Express支持同一路径绑定多个响应函数

app.all('test/:user',function(req,res,next){
    res.send("all method is call");
    next();
});

app.get('/test/:user',function(req,res){
    res.send("user: " + req.params.user); 
});
1
2
3
4
5
6
7
8

但是我们访问都只会返回一次。 Express提供了路由控制权转移的方法,即next()函数,通过调用则将控制权交给后面的规则