能否一次性转义Backbone.Router多路由的所有参数?
统一转义Backbone.Router所有路由参数的解决方案
当然可以!你完全可以通过重写Backbone.Router的execute方法来实现统一的参数转义,彻底摆脱在每个路由处理函数里重复编写转义代码的麻烦,完美贴合DRY(Don't Repeat Yourself)原则。
核心思路:利用Backbone Router的execute钩子
Backbone.Router内置了execute方法,它是路由匹配成功后触发处理函数的核心入口。默认情况下,这个方法只是直接调用对应的路由回调并传递原始参数。我们可以重写这个方法,在调用回调前统一对所有参数进行转义处理。
实现代码(CoffeeScript)
class MyRouter extends Backbone.Router routes: "student/:id/:name" : "student" "teacher/:tid/:tname" : "teacher" "teacher/:tid/:tname/share" : "teacher_share" # 重写execute方法,添加统一参数转义逻辑 execute: (callback, args, routeName) -> # 对路由传递的所有参数进行转义 escapedArgs = args.map (arg) -> _.escape(arg) # 调用原路由处理函数,传入转义后的参数 callback?.apply(@, escapedArgs) # 路由处理函数无需再手动转义参数,直接使用即可 student: (id, name) -> # id和name已经是转义后的安全值 # do stuff teacher: (tid, tname) -> # tid和tname已经是转义后的安全值 # do stuff teacher_share: (tid, tname) -> # tid和tname已经是转义后的安全值 # do stuff
代码解释
- 重写
execute方法:这个方法接收三个参数:callback:匹配到的路由对应的处理函数args:路由中提取的原始参数数组routeName:当前匹配的路由名称(可选,这里我们暂时用不到)
- 统一转义参数:用
Array.map遍历args,对每个参数调用_.escape进行转义,得到转义后的参数数组escapedArgs - 调用原处理函数:用
apply将转义后的参数传递给原始的路由处理函数,确保后续逻辑使用的都是安全参数
备选方案:初始化时包装路由处理函数
如果你更倾向于通过包装函数的方式实现,也可以在Router初始化时遍历所有路由处理函数,为它们添加自动转义逻辑:
class MyRouter extends Backbone.Router routes: "student/:id/:name" : "student" "teacher/:tid/:tname" : "teacher" "teacher/:tid/:tname/share" : "teacher_share" initialize: -> # 遍历所有路由,包装处理函数 for _, handlerName of @routes originalHandler = @[handlerName] if _.isFunction(originalHandler) # 用_.wrap包装原函数,添加参数转义逻辑 @[handlerName] = _.wrap originalHandler, (original, ...args) -> escapedArgs = args.map (arg) -> _.escape(arg) original.apply(@, escapedArgs) # 路由处理函数直接使用转义后的参数 student: (id, name) -> # do stuff # ... 其他路由方法同上
这种方式同样能达到统一转义的效果,但重写execute方法更贴合Backbone的设计初衷,代码也更简洁易维护。
内容的提问来源于stack exchange,提问作者Nitanshu
相关产品推荐
相关产品推荐

