Skip to content
This repository has been archived by the owner on May 7, 2024. It is now read-only.

Latest commit

 

History

History
executable file
·
181 lines (118 loc) · 12.3 KB

RouteTargetSyntax.md

File metadata and controls

executable file
·
181 lines (118 loc) · 12.3 KB

自定义路由

概述

Sails允许在你的config/routes.js文件中明确用不同的方法路由URL。每一条路由都包括地址目标,如下:

'GET /foo/bar': 'FooController.bar'
^^^address^^^^  ^^^^^^target^^^^^^^

路由地址

路由地址指示URL应该匹配什么,以便应用目标定义的操作以及选项。一条路由地址包括可选的verb和一个必选的路径:

'POST  /foo/bar'
^verb^ ^^path^^

如果没有verb指定,目标将会被应用到匹配路径的任何请求,忽略使用的HTTP方法(GET/POST/PUT等)。注意路径中的初始字符/--所有的路径都应该以该字符作为起始字符否则会出错。

通配符和动态参数

为了像foo/bar一样指定一个静态路径,你可以使用*作为通配符:

'/*'

将会匹配到所有的路径,如:

'/user/foo/*'

该规则将会匹配所有的以/user/foo开始的路径。

注意:当使用带有通配符的路由,比如'/*',这也会匹配到请求静态assets(也就是/js/dependencies/sails.io.js)并覆盖它们。为了避免这个,考虑使用下面描述skipAssets选项。

你可以通过使用:paramName通配符语法而不是使用*来匹配名字参数中的某一部分:

'/user/foo/:name/bar/:age'

将会匹配相同的URL如下:

'/user/foo/*/bar/*'

但是也会分别提供路由的通配符部分的值到路由操作req.param('name')req.param('age')

地址中的正则表达式

除了通配符语法,你可能也使用正则表达式来定义一条路由匹配的URLs。使用正则表达式来定义地址的语法如下:

"r|<regular expression string>|<comma-delimited list of param names>"

字母“r”后面跟着一个管道符|,一条正则表达式没有分隔符,另一个管道符后面应该跟着一组参数名字--应该被映射到加括号的组中。比如:

"r|^/\\d+/(\\w+)/(\\w+)$|foo,bar": "MessageController.myaction"

将会匹配/123/abc/def,运行MessageController中的myaction的动作并提供abcdef的值分别作为req.param('foo')req.param('bar')的结果。

注意双反斜杠\\d\\w是为了转义之用。

关于路由顺序

当在你的地址中使用通配符或者正则表达式,请注意在你的config/routes.js中的路由顺序。URL将会匹配从上到下的匹配地址列表。如果你在这个规则中有两条配置:

'/user': 'UserController.doSomething',
'/*'   : 'CatchallController.doSomethingElse'

那么到/user的请求将不会匹配到第二条配置除非第一条配置的操作在它的代码中调用next(),这种配置是不鼓励的(只有policies才应该调用next())。除非你使用的东西非常先进,那么可以安全地假设每一条请求至多被一条路由处理在你的config/routes.js文件。

路由目标

自定义的请求中的地址那一部分是指示URL应该匹配的路由,那么目标那一部分是指示Sails应该在匹配之后做些什么操作。一条目标可以使用多种不同格式中的一个。在一些情况下你也许想要将多条目标串成一个单一的地址通过将它们放到一个数组中,但是大部分情况是每一条地址只有一条目标。目标的不同种类型将在下面讨论,并且也会讨论应用到它们中的各种选项。

控制器/动作的目标语法

目标的最常见的类型是绑定一条路由到一个自定义的controller action,下面的4条路由都是等价的:

'GET /foo/go': 'FooController.myGoAction',
'GET /foo/go': 'Foo.myGoAction',
'GET /foo/go': {controller: "Foo", action: "myGoAction"},
'GET /foo/go': {controller: "FooController", action:"myGoAction"},

每一条映射GET /foo/go到在api/controllers/FooController.js控制器中的myGoAction动作。如果没有这样的动作或者控制器存在,Sails将会输出一个错误信息并忽略该路由。否则,无论什么时候一条GET请求到**/foo/go**,那动作的代码都会执行。

在这个语法中的控制器和动作的名字是区分大小写的。

注意blueprint API默认地添加一些动作到你的控制器中(比如"find", "create", "update" and "delete"),所有的这些动作都是在路由中可用的:

'GET /foo/go': 'UserController.find'

假设你有api/controllers/UserController.js文件和一个api/models/User.js文件,在浏览器中浏览**/foo/go**将会使用上述的配置,运行默认的“find*” blueprint动作来显示所有的User模型的列表。如果你有一个自定义的动作叫做find在UserController,该动作会替换掉默认的动作而被执行。

视图的目标语法

另外一个常见的目标是绑定一条路由到一个视图中。这个语法非常容易,直接指向视图对应的路径,不需要文件的后缀名:

'GET /home': {view: 'home/index'}

这个将映射GET /home到存储在views/home/index.ejs(假设使用EJS模板引擎)的视图。只要对应的视图存在,那么GET请求到**/home**的将会显示。

注意这条路由将会直接被绑定到视图中,没有任何策略应用到这个例子中,参考 this StackOverflow question

Blueprint 的目标语法

在一些情况下你可能需要映射一个非标准的地址到一个Sails的Blueprint动作。比如如果你有一个控制器和动作分别叫做UserControllerUser,那么Sails将会自动映射GET /user到“find” blueprint 动作并返回一个User记录的列表。如果你想要映射一个不同地址到该动作上,你可以使用下面的语法:

'GET /findAllUsers': {model: 'user', blueprint: 'find'},
'GET /user/findAll': {blueprint: 'find'}

注意在这个配置里,modelblueprint的属性都要被设置,但是只有第二种也就是只有blueprint会被使用。在第二种配置中,删去model属性会导致Sails去检查地址并猜测模型是User。你可以覆盖掉这个通过明确地设置Model为别的:

'GET /user/findAll': {blueprint: 'find', model: 'pet'}

即使你很少想要这样做,但是仍然建议你不要这样做,因为它会让你的app的API变得混乱和让人混淆。

如果你指定一个没有扩展的model或者blueprint在你的配置中,Sails将会输出一个错误并忽略掉这个路由。

你也可以使用这个语法去映射一条路由到默认的blueprint动作中的一个即使你在你的控制器中已经重写那动作。

重定向语法

你可以重定向一条地址到另一条--既可以在你的服务器上也可以是完全地在别的服务器上--只需指定一条重定向的URL字符串如下:

'/alias' : '/some/other/route'
'GET /google': 'http://www.google.com'

当在你的Sails app中重定向的时候小心重定向死循环!

注意的是当重定向的时候,原始请求的HTTP方法(和其他额外的头部参数)将会丢失,并且请求将会被传输到一条简单的GET请求。在上述的实例中,一条POST请求到**/alias的将会得到一条GET请求到/some/other/route**的结果。这就有点依赖于浏览器的行为了,但是建议你不要期望请求方法以及数据从一条重定向中。

响应的目标语法

你可以直接映射一个地址到一条默认的或者自定义的响应通过使用下面的语法:

'/foo': {response: 'notFound'}

在你的api/responses文件夹中简单地指定响应文件的名字,不需要**.js**后缀名。在这条语法中响应名字是区分大小写的。如果你尝试绑定一条路由到一条没有扩展的响应,Sails将会输出错误并忽略这条路由。

策略的目标语法

在大部分情况下,你想要使用config/policies.js配置文件来应用policies到你的控制器的动作中。然而也有些时候当你想要直接应用一条策略到一条自定义的路由:尤其当你想要使用view或者[blueprint]((http://sailsjs.org/documentation/concepts/Routes/RouteTargetSyntax.html?q=blueprint-target-syntax)目标语法的时候。下面的策略目标语法是:

'/foo': {policy: 'myPolicy'}

然而,你总是想要串联策略到至少一种类型的目标中,使用这个数组:

'/foo': [{policy: 'myPolicy'}, {blueprint: 'find', model: 'user'}]

这个将会应用myPolicy策略到你的路由并且,如果通过的话,将会继续为User模型运行find的blueprint。

路由目标选项

除了上面讨论的各种路由目标语法提到的选项之外,其他你会添加到路由目标对象中的属性将会被传递到路由操作器在req.options对象中。这里有一些保留的属性可以用于影响路由操作性的行为。列表如下:

Property Applicable Target Types Data Type Details
skipAssets all ((boolean)) Set to true if you don't want the route to match URLs with dots in them (e.g. myImage.jpg). This will keep your routes with wildcard notation from matching URLs of static assets. Useful when creating URL slugs.
skipRegex all ((regexp)) If skipping every URL containing a dot is too permissive, or you need a route's handler to be skipped based on different criteria entirely, you can use skipRegex. This option allows you to specify a regular expression or array of regular expressions to match the request URL against; if any of the matches are successful, the handler is skipped. Note that unlike the syntax for binding a handler with a regular expression, skipRegex expects actual RegExp objects, not strings.
locals controller, view, blueprint, response ((dictionary)) Sets default local variables to pass to any view that is rendered while handling the request.
cors all ((dictionary)) or ((boolean)) or ((string)) Specifies how to handle requests for this route from a different origin. See the main CORS documentation for more info.
populate blueprint ((boolean)) Indicates whether the results in a "find" or "findOne" blueprint action should have associated model fields populated. Defaults to the value set in config/blueprints.js.
skip, limit, sort, where blueprint ((dictionary)) Set criteria for "find" blueprint. See the queries reference for more info.