如果您要实现搜索功能或其他需要多个可选参数的功能,最好使用查询字符串参数。您可以提供全部、部分或不提供,并将它们按任何顺序排列,这样就可以了。
// Anything Goes
/controller/action?a=123&b=456&c=789
/controller/action?c=789&a=123&b=456
/controller/action?b=456&c=789
/controller/action?c=789
/controller/action
另一方面,如果你使用 URL 路径和路由,一个参数只有在它的右边没有另一个参数时才可以是可选的。
// OK
/controller/action/123/456/789
/controller/action/123/456
/controller/action/123
// Not OK
/controller/action/123/456/789
/controller/action/456/789
/controller/action/789
customizing routing to be able to pass optional values in any order 有可能,但是当查询字符串自然适合这种情况时,这似乎还有很长的路要走。
另一个需要考虑的因素是放入 URL 中的值是否包含需要编码的 unsafe characters。对 URL 的 path 进行编码是一种糟糕的形式,有时是不可行的,但是对于可以将哪些类型的编码字符放入查询字符串的规则更加宽松。由于 URL 不允许使用空格,因此更适合使用查询字符串中的空格对多字文本搜索字段进行编码(按原样保留),而不是尝试找到用空格替换空格的解决方案- 放入查询字符串,然后在运行查询时必须将其更改回服务器端的空格。
search = "foo bar"
// Spaces OK
/controller/action?search=foo%20bar (works fine and server is able to interpret)
// Spaces Not OK
/controller/action/foo bar/ (not possible)
/controller/action/foo%20bar/ (may work, but a questionable design choice)
/controller/action/foo-bar/ (may work, but requires conversion on the server)
最后,另一个值得考虑的选择是使用 POST 而不是 GET,因为这意味着这些值根本不需要在 URL 中。