#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的主要内容,如果未能解决你的问题,请参考以下文章

java面试题——中间件&&数据库&&redis

消息中间件--ActiveMQ&JMS消息服务

ExpressJS:承诺和错误处理中间件

RTOS中间件bror&freertos实现bror接口

RTOS中间件bror&freertos实现bror接口

RTOS中间件bror&freertos实现bror接口