express的新开发人员往往对路由处理程序和中间件之间的区别感到困惑。因此他们也对app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()方法的区别感到困惑。
在本文中,我将解释中间件和路由处理程序之间的区别。以及如何正确使用app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()方法。
路由处理
app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()全部是用来定义路由的。这些方法都用于定义路由。路由用于处理HTTP请求。路由是路径和回调的组合,在请求的路径匹配时执行。回调被称为路由处理程序。
它们之间的区别是处理不同类型的HTTP请求。例如: app.get()方法仅仅处理get请求,而app.all()处理GET、POST等请求。
下面是一个例子,如何定义一个路由:
var app = require("express")(); app.get("/", function(req, res, next){ res.send("Hello World!!!!"); }); app.listen(8080);
每个路由处理程序都获得对当前正在提供的HTTP请求的请求和响应对象的引用。
可以为单个HTTP请求执行多个路由处理程序。这是一个例子:
var app = require("express")(); app.get("/", function(req, res, next){ res.write("Hello"); next(); }); app.get("/", function(req, res, next){ res.write(" World !!!"); res.end(); }); app.listen(8080);
这里第一个句柄写入一些响应,然后调用next()。 next()方法用于调用与路径路径匹配的下一个路由处理程序。
路由处理程序必须结束请求或调用下一个路由处理程序。
我们还可以将多个路由处理程序传递给app.all(),app.get(),app.post(),app.delete()和app.put()方法。
这是一个证明这一点的例子:
var app = require("express")(); app.get("/", function(req, res, next){ res.write("Hello"); next(); }, function(req, res, next){ res.write(" World !!!"); res.end(); }); app.listen(8080);
中间件
中间件是一个位于实际请求处理程序之上的回调。它采用与路由处理程序相同的参数。
要了解中间件,我们来看一个带有dashboard和profile页面的示例站点。要访问这些页面,用户必须登录。还会记录对这些页面的请求。
以下是这些页面的路由处理程序的代码:
var app = require("express")(); function checkLogin(){ return false; } function logRequest(){ console.log("New request"); } app.get("/dashboard", function(req, res, next){ logRequest(); if(checkLogin()){ res.send("This is the dashboard page"); } else{ res.send("You are not logged in!!!"); } }); app.get("/profile", function(req, res, next){ logRequest(); if(checkLogin()){ res.send("This is the dashboard page"); } else{ res.send("You are not logged in!!!"); } }); app.listen(8080);
这里的问题是有很多重复的代码,即我们不得不多次使用logRequest()和checkLogin()函数。这也使得更新代码变得困难。因此,为了解决这个问题,我们可以为这两条路径编写一条通用路径。
这是重写的代码:
var app = require("express")(); function checkLogin(){ return false; } function logRequest(){ console.log("New request"); } app.get("/*", function(req, res, next){ logRequest(); next(); }) app.get("/*", function(req, res, next){ if(checkLogin()){ next(); } else{ res("You are not logged in!!!"); } }) app.get("/dashboard", function(req, res, next){ res.send("This is the dashboard page"); }); app.get("/profile", function(req, res, next){ res.send("This is the dashboard page"); }); app.listen(8080);
这里的代码看起来更清晰,更易于维护和更新。这里将前两个定义的路由处理程序称为中间件,因为它们不处理请求,而是负责预处理请求。
Express为我们提供了app.use()方法,该方法专门用于定义中间件。 app.use()方法可能看起来与app.all()类似,但它们之间存在很多差异,这使得app.use()非常适合于声明中间件。让我们看看app.use()方法是如何工作的:
app.use() 和 app.all() 的不同:
CALLBACK
app.use()只需要一个回调,而app.all()可以进行多次回调。
PATH
app.use()只查看url是否以指定路径开头,app.all()匹配完整路径。
这里有一个例子来说明:
app.use( "/product" , mymiddleware); // will match /product // will match /product/cool // will match /product/foo app.all( "/product" , handler); // will match /product // won't match /product/cool <-- important // won't match /product/foo <-- important app.all( "/product/*" , handler); // won't match /product <-- Important // will match /product/cool // will match /product/foo
NEXT()
中间件内的next()调用下一个中间件或路由处理程序,具体取决于接下来声明的那个。但是路由处理程序中的next()仅调用下一个路由处理程序。如果接下来有中间件,则跳过它。因此,必须在所有路由处理程序之前声明中间件。
这里有一个例子来说明:
var express = require('express'); var app = express(); app.use(function frontControllerMiddlewareExecuted(req, res, next){ console.log('(1) this frontControllerMiddlewareExecuted is executed'); next(); }); app.all('*', function(req, res, next){ console.log('(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next'); next(); }); app.all('/hello', function(req, res, next){ console.log('(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next'); next(); }); app.use(function frontControllerMiddlewareNotExecuted(req, res, next){ console.log('(4) this frontControllerMiddlewareNotExecuted is not executed'); next(); }); app.get('/hello', function(req, res){ console.log('(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response'); res.send('Hello World'); }); app.listen(80);
现在我们看到了app.use()方法的唯一性以及它用于声明中间件的原因。
让我们重写我们的示例站点代码:
var app = require("express")(); function checkLogin(){ return false; } function logRequest(){ console.log("New request"); } app.use(function(req, res, next){ logRequest(); next(); }) app.use(function(req, res, next){ if(checkLogin()){ next(); } else{ res.send("You are not logged in!!!"); } }) app.get("/dashboard", function(req, res, next){ res.send("This is the dashboard page"); }); app.get("/profile", function(req, res, next){ res.send("This is the dashboard page"); }); app.listen(8080);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
3 详细说明 ffmpeg的每个转换过程像下图描述的程序 _______ ______________ | | | | | input | demuxer | encoded data | decoder | file | ---------> | packets | -----+ |__
本文向大家介绍Nginx配置文件nginx.conf详细说明,包括了Nginx配置文件nginx.conf详细说明的使用技巧和注意事项,需要的朋友参考一下 在此记录下Nginx服务器nginx.conf的配置文件说明, 部分注释收集与网络. 以上是一些基本的配置,使用Nginx最大的好处就是负载均衡 如果要使用负载均衡的话,可以修改配置http节点如下: 以上就是本文的全部内容,希望对大家的学习有
本文向大家介绍redis3.2配置文件redis.conf详细说明,包括了redis3.2配置文件redis.conf详细说明的使用技巧和注意事项,需要的朋友参考一下 Redis启动的时候,可以指定配置文件,如下: Redis.conf文件内容详细说明:
本文向大家介绍ffmpeg中文参数详细说明,包括了ffmpeg中文参数详细说明的使用技巧和注意事项,需要的朋友参考一下 FFMPEG 3.4.1 版本参数详细说明 用法:ffmpeg [options] [[infile options] -i infile] … {[outfile options] outfile} … FFMPEG获得帮助: -h - 打印基本选项 -h long - 打印更
templates 文件夹 官方一系列模版所在的文件夹,包括了图片、xml、html以及相关配置文件等。通过对这里的了解和修改,我们可以做出自己的皮肤模版,然后一键生成,实现批量的工作流。当然,正常情况下,你也无需从这里拷贝,因为在droplet过程中会自动生成。部分模版在默认droplet过程中并没有使用到。 viewer 文件夹 krpano 下载包的官方插件、引擎、案例的存放位置,同时也是让
说明文件 CONTRIBUTORS:作者信息 README.md:主说明文件 doc/doxygen.cfg:执行doxygen生成文档时的配置文件。