一、工作原理
当通过浏览器访问app.js建立的服务器时,会看到一个简单的页面,实际上它已经完成了许多透明的工作,
当访问http://localhost:3000,浏览器会向服务器发送请求,包括请求的方法、路径、HTTP协议版本和请求头信息。app会解析请求的路径,调用相应的逻辑,app.js中有app.get("/",routes.index)通过res.render("index",{title:"pcat"})调用视图模版index,传递title变量,最终视图生成HTML页面,返回给浏览器。
浏览器接收到内容后,通过分析需要获取/stylesheets/style.css,因此会再次向服务器发起请求,app.js并没有一个路由规则指派到/stylessheets/style.css,但app通过app.use(express.static(__dirname+'/public'))配置了静态文件服务器,因此会定向到app.js所在目录下的/public/stylessheets/style.css拿去这个文件。
这是一个典型的MVC架构,浏览器发送请求,由路由控制接受,根据不同的路径定向到不同的服务器,控制器处理用户具体的请求,可能会访问数据库中的对象,即模型部分,生成视图的HTML,最后再由控制器返回给浏览器,完成一次请求。
二、创建路由规则
当我们在浏览器访问http://localhost:3000/pcat的时候,服务器响应头返回404 Not found错误
这是因为/pcat是一个不存在的路由规则,而且它也不是一个public目录下的文件,所以响应404
假设我们创建一个/pcat的的路由规则。
app.get("/pcat",routes.pcat)。在index.js中增加函数pcat
exports.pcat=function(req,res){
res.send('The time is '+new Date().toString());
}
服务器在开始监听之前,设置好了所有的路由规则,当请求到达时直接分配到相应函数。app.get是路由规则创建函数,
参数一:请求的路径
参数二:是一个回调函数,该路由规则被触发时调用回调函数,并传递req(请求信息)和res(响应信息)两个参数。
三、路径匹配
上面讲到了为固定的路径设置路由规则,Express还提供更高级的路径匹配模式。
1.app.get('/user/:username',function(req,res){
res.send("user :"+req.params.username);
});
路径规则/user/:username会被自动编译成正则表达式,类似于\/user\/([^\/]+)\/?这样的形式,路径参数可以相应函数中通过req.params的属性访问
2.路径规则同样支持javascript正则表达式,例如:app.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请求方法都设计了不同的路由绑定函数,例如前面全部是app.get,标识该路径绑定了GET请求,向这个路径发起其他方式的请求不会被响应。
GET app.get(path,callback)
POST app.post(path,callback)
PUT app.put(path,callback)
DELETE app.delete(path,callback)
...
...
所有方法 app.all(path,callback,next)
怎么使用?
绑定一个POST请求,可以使用app.post(path,callback)的方法设置路由规则。
app.all函数,它支持把所有的请求方法都绑定到同一个相应函数,是一个非常灵活的函数。
五、控制权转移
Express支持同一路径绑定多个相应函数
app.all('/test/:user',function(req,res,next){
//我们在这里验证用户名是否存在。
//如果存在直接send或者调用next(new Error('用户已经存在'));
//如果不存在我们调用next()把控制权交给下一个路由规则
console.log("all methods is call");
next();
res.send('哈哈');
});
app.get('/test/:user',function(req,res){
res.send("user:"+req.pararms.user)
})
但是我们访问都会只返回一次。
Exress提供了路由控制权转移的方法,即next()函数,通过调用则将控制权交给后面的规则。