#2 中间件, 路由,router,https
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#2 中间件, 路由,router,https相关的知识,希望对你有一定的参考价值。
参考技术A本章主要详细的学习Express最大的2个特性:中间件和路由
中间件在很多框架中都存在,Express中间件将大的请求处理函数(request handler)拆分为多个小的部分进行处理。中间件可以对request,response对象进行逻辑控制,从而返回自己需要的结果。
Express使用 app.use() 方法将中间件添加到中间件栈中,形成函数数组,采取 FIFO (First In First Out) 的方式,对数据依次的处理。
使用NodeJS框架的server,客户端发起请求到接收响应的流程大致如下:
中间件栈结束处理,要么反生错误退出,要么调用 res.end() 方法,或者是 res.send() , res.sendFile() 方法(这2个方法内部自动调用 res.end() 方法)。
最常见的中间件形式为:
最后一个中间件\'next\'可以省略,比如未匹配到路由,返回404:
下面实例用来编写2个中间件,一个用来记录日志,一个用来发送文件:
当然可以使用第3方提供的 morgan 中间件来替代上面的记录日志中间件和Express自带的 express.static() 来替代文件的发送,上面的例子可以改写为:
其签名为:
如果进入 错误模式 ,则其它的正常的middleware 都不处理,所以一般错误处理放在最后,就像promise 中的 \'catch\' 一样。
给 next() 添加一个参数,一般是一个错误对象,则可进入错误模式:
示例:
上一章对路由做了简单的介绍,路由简单点说就是: URL + HTTP 请求动作(\'GET\',\'POST\',\'PUT\',\'DELETE\'...) ---> 对应响应处理函数 。
现在将对路由将做更为详细的介绍,比如 静态文件路由问题, router 的使用 。
上一章中谈到了路径匹配的3中方式:字符串,字符串模版,正则表达式。下面看几个示例:
随带讲一下 req.params 这个属性:
当使用命名路由参数时,这个属性是一个对象,例如 \'/user/:name\', \'name\' 则为\'req.params\'对象的一个属性
当使用正则表达式来定义路由路径时,捕获到的组则可通过 \'req.params[n]\' 来获取:
在搜索引擎中查询,常会碰到这种形式的路由 \'/search?q=javascript20%tutorials\',可以使用下面路由进行处理:
使用 req.query 可以获取查询字符串:
一个router就是中间件(middlewares)和路由(routes)的一个单独的实例。可以将一个大的应用拆分为很多小的应用。每个express app都有一个内置的app router。
使用 express.Router() 实例化一个router
主app:
router:
router有几个方法,下面介绍一下:
可选参数用于定义router的行为,有3个可选参数:
这个方法和 router.METHOD() 很像,只是这个方法匹配所有的 HTTP 请求动作(\'GET\', \'POST\'...)
对指定路径下的全局逻辑十分有用,比如:
返回单一路由实例,可以链式调用,避免重复
以下几种情形:
1. 比如说我们访问 \' www.example.com/dog.jpg\' , 现在想通过 \' www.example.com/gallery/dog.jpg\' ,可以通过下面方式
2. 多个静态文件路径,有时候文件可能在不同的文件夹,我们可以多次调用 \'express.static()\' 方法来添加静态文件的位置
这种情形可以存在下面几种方式:
3. 上面的第4中情形,可以通过下列方式解决
现在用户可以同时获取\'/public\'和\'/uploads\'的资源,比如 \'/public/cat.png\',\'/uploads/dog.png\'
HTTPS添加一层安全协议层(TSL(相对ssl更好) 或 SSL)。
通俗解释:每个设备都有一个公共密钥(google称之为证书比如CAs)和一个私有密钥,发送信息,通过私有密钥加密,对方接收信息,通过公共密钥识别,然后通过自身的私有密钥解密。
为了使用HTTPS需要以下步骤:
本章主要详细的将中间件的运行原理,中间件的定义形式;使用路由时的一些方法,如何使用 router 将app分割成小的app,及router常用的一些方法apis,最后粗略的讲了一下如何使用https模块,对于https协议怎么进行处理。
2017年3月20日 19:40:57
使用 Gorilla MUX 和 Negroni 子路由中间件
【中文标题】使用 Gorilla MUX 和 Negroni 子路由中间件【英文标题】:Subroutes middlewares with Gorilla MUX and Negroni 【发布时间】:2017-06-21 19:31:49 【问题描述】:我正在尝试仅在某些路由上添加中间件。我写了这段代码:
func main()
router := mux.NewRouter().StrictSlash(false)
admin_subrouter := router.PathPrefix("/admin").Subrouter()
//handlers.CombinedLoggingHandler comes from gorilla/handlers
router.PathPrefix("/admin").Handler(negroni.New(
negroni.Wrap(handlers.CombinedLoggingHandler(os.Stdout, admin_subrouter)),
))
admin_subrouter.HandleFunc("/articles/new", articles_new).Methods("GET")
admin_subrouter.HandleFunc("/articles", articles_index).Methods("GET")
admin_subrouter.HandleFunc("/articles", articles_create).Methods("POST")
n := negroni.New()
n.UseHandler(router)
http.ListenAndServe(":3000", n)
我希望只看到前缀为 /admin 的路径的请求日志。我在执行“GET /admin”时确实看到了一条日志行,但在执行“GET /admin/articles/new”时却没有。我通过蛮力尝试了其他组合,但我无法得到它。我的代码有什么问题?
我看到了其他方法,比如在每个路由定义上包装 HandlerFunc,但我想为前缀或子路由器做一次。
我在那里使用的日志记录中间件用于测试,也许 Auth 中间件更有意义,但我只是想让它工作。
谢谢!
【问题讨论】:
【参考方案1】:问题是您创建子路由/admin
的方式。完整的参考代码在这里https://play.golang.org/p/zb_79oHJed
// Admin
adminBase := mux.NewRouter()
router.PathPrefix("/admin").Handler(negroni.New(
// This logger only applicable to /admin routes
negroni.HandlerFunc(justTestLogger),
// add your handlers here which is only appilcable to `/admin` routes
negroni.Wrap(adminBase),
))
adminRoutes := adminBase.PathPrefix("/admin").Subrouter()
adminRoutes.HandleFunc("/articles/new", articleNewHandler).Methods("GET")
现在,访问这些 URL。您只会看到 /admin
子路由的日志。
【讨论】:
这行得通,谢谢。我想使用 Gorilla 包处理程序提供的中间件。 然后,我可以使用 Gorilla 处理程序做:router.PathPrefix("/admin").Handler(negroni.New( negroni.Wrap(handlers.CombinedLoggingHandler(os.Stdout, adminBase)), ))
是的,您可以使用它,只是为了演示子路由器的定义,我在示例中没有使用它。对此感到抱歉。
使用子路由器上的确切代码作为基础。处理程序函数没有被调用。以上是关于#2 中间件, 路由,router,https的主要内容,如果未能解决你的问题,请参考以下文章