【问题标题】:Ignore the presence or absence of a trailing slash in Symfony Routing忽略 Symfony 路由中是否存在斜杠
【发布时间】:2018-11-17 09:48:38
【问题描述】:

我正在开发基于 Symfony 4.1.0 的微服务,它在 config/routes.yaml 中定义了以下 REST API:

import:
    path: /sip/calls/
    controller: App\Controller\ApiController::import
    methods: [POST]

问题是对/sip/calls 的POST 请求导致NotFoundHttpException(找不到“POST /sip/calls”的路由)。如果我从 config/routes.yaml 中的路由路径中删除尾部斜杠,则对 /sip/calls 的请求会通过,但 /sip/calls/ 会停止工作。

为什么会这样?如何让它忽略斜线或它的缺失?

【问题讨论】:

  • 这是一个众所周知的功能。您可以搜索并阅读一些讨论。您的路线实际上适用于 GET 但不适用于 POST。可悲的事实是,就 http 而言,添加尾部斜杠确实使它成为不同的资源。您可以使用一些正则表达式来绕过它,或者只定义两条路线。

标签: php symfony symfony4 symfony-routing


【解决方案1】:

正如解释:Redirecting URLs with Trailing Slashes Symfony 4.1 通过创建重定向 301 在内部处理此问题。但问题是此重定向不适用于 POST 请求。

正如这里提到的Why doesn't HTTP have POST redirect 理论上你可以使用重定向 307 或 308,但我过去遇到了一些问题,所以我选择了带有斜杠的重复路径的简单解决方案。

【讨论】:

    【解决方案2】:

    这是@LukaszJakubek 指出的预期行为。如果您需要以两种方式匹配路线,您可以分配多条路线,它应该可以工作:

    #config/routes.yaml
    with_slash:
        path: test/
        controller: App\Controller\TestController::something
        methods: [POST]
    
    without_slash:
        path: test
        controller: App\Controller\TestController::something
        methods: [POST]
    

    使用调试命令时的结果:

    bin/console router:match /test --method=POST
    
    
    
    [OK] Route "without_slash" matches
    
    
    +--------------+---------------------------------------------------------+
    | Property     | Value                                                   |
    +--------------+---------------------------------------------------------+
    | Route Name   | without_slash                                           |
    | Path         | /test                                                   |
    | Path Regex   | #^/test$#sD                                             |
    | Host         | ANY                                                     |
    | Host Regex   |                                                         |
    | Scheme       | ANY                                                     |
    | Method       | POST                                                    |
    | Requirements | NO CUSTOM                                               |
    | Class        | Symfony\Component\Routing\Route                         |
    | Defaults     | _controller: App\Controller\TestController::something   |
    | Options      | compiler_class: Symfony\Component\Routing\RouteCompiler |
    +--------------+---------------------------------------------------------+
    bin/console router:match /test/ --method=POST
    
    
    
    [OK] Route "with_slash" matches
    
    
    +--------------+---------------------------------------------------------+
    | Property     | Value                                                   |
    +--------------+---------------------------------------------------------+
    | Route Name   | with_slash                                              |
    | Path         | /test/                                                  |
    | Path Regex   | #^/test/$#sD                                            |
    | Host         | ANY                                                     |
    | Host Regex   |                                                         |
    | Scheme       | ANY                                                     |
    | Method       | POST                                                    |
    | Requirements | NO CUSTOM                                               |
    | Class        | Symfony\Component\Routing\Route                         |
    | Defaults     | _controller: App\Controller\TestController::something   |
    | Options      | compiler_class: Symfony\Component\Routing\RouteCompiler |
    +--------------+---------------------------------------------------------+
    

    【讨论】:

    • 太棒了。这似乎也适用于注释。谢谢。
    • 使用前缀时这对我不起作用 - 即在捆绑包中定义的路由并在使用该捆绑包的应用程序中添加前缀
    • @meridius 这取决于捆绑包提供路由的方式。从理论上讲,您应该能够覆盖它们。也许您可以针对您的具体问题提出一个新问题,即哪个捆绑包导致您的问题以及您的(和捆绑包的)路由配置?
    猜你喜欢
    • 1970-01-01
    • 2018-05-19
    • 2018-10-28
    • 1970-01-01
    • 2011-03-22
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多