允许没有参数的 Symfony2 路由的尾部斜杠?

Posted

技术标签:

【中文标题】允许没有参数的 Symfony2 路由的尾部斜杠?【英文标题】:Allow trailing slash for Symfony2 route without params? 【发布时间】:2012-04-05 06:13:02 【问题描述】:
acme_admin_dashboard:
    pattern:  /_locale/admin
    defaults:  _controller: AcmeBundle:Admin:dashboard 

我希望通过/en/admin/en/admin/ 可以访问这条路线。我将如何实现这一目标?

【问题讨论】:

看到这个cookbook entry。 【参考方案1】:

您也可以简单地在 .htaccess 文件中使用重写规则:

假设您已经定义了这样的路线:

news:
  url:   /news
  param:  module: news, action: index 

这将与 http://something.something/news 匹配,但不会与 http://something.something/news/ 匹配 您可以添加带有尾部斜杠的附加路由,但您也可以简单地在 .htaccess 文件中使用此重写规则:

RewriteRule ^(.+)/$ http://%HTTP_HOST/$1 [R=301,L]

http://symfony-blog.driebit.nl/2010/07/url-routes-with-or-without-a-trailing-slash/

【讨论】:

我喜欢这个解决方案。将问题限制在服务器层似乎是合适的,因为根本不需要应用程序逻辑。 ^ 但它使应用程序按预期工作所必需的东西..【参考方案2】:

我找到了在路由中添加斜杠的解决方案。

表示两个链接都在工作www.example.com/route/of/some/pagewww.example.com/route/of/some/page/。你可以这样做:

如果你的路线看起来像

/**
 * @Route("/route/of/some/page")
 */
public function pageAction() 

更改为

/**
 * @Route("/route/of/some/pagetrailingSlash", requirements="trailingSlash" = "[/]0,1", defaults="trailingSlash" = "/")
 */
public function pageAction() 

【讨论】:

完全没有意义,只需在接受的答案中使用斜杠即可。 我喜欢它背后的创意! 这不是没有意义的。它适用于不允许重定向的预检 OPTIONS 请求。 不错!正如@r0ber7 提到的,它删除了 301 重定向 :) 如果您最终为所有路线都这样做,会使您的代码变得混乱 - 但我喜欢这个想法! 如果您的路由被无法遵循 301 重定向的客户端使用,这将非常有用。这样,无论是否带有斜杠,您都会得到 200 响应。【参考方案3】:

只需输入:

/**
* @Route("/route/of/some/page/")
*/

所以

www.example.com/route/of/some/page 

www.example.com/route/of/some/page/

被接受...

【讨论】:

但是默认情况下所有链接都带有斜杠..这似乎有点粗糙 天啊,你不想这样做!它确实 301 - 永久移动,因此不会重新发送 POST 参数! (maltronic.io/2015/08/09/…)【参考方案4】:

我喜欢@Kuchengeschmack 的回答 (https://***.com/a/11078348/593957),因为它不会触发外部重定向。

这是一个 yaml 版本:

acme_admin_dashboard:
    pattern:  /_locale/admintrailingSlash
    defaults:  _controller: AcmeBundle:Admin:dashboard, trailingSlash : "/" 
    requirements:  trailingSlash : "[/]0,1" 

【讨论】:

在侧节点上,这在使用 FOSRestBundle 时特别​​有用,因为这样您的 REST 接口不会返回外部重定向。 你可以简单地使用\?作为要求,你可以省略默认定义 我发现这个解决方案对于它所做的小事情来说非常繁重......像 ine Damien 的答案那样编写规则会更好,而且效果很好。【参考方案5】:

我在前端控制器(app.php / app_dev.php)中破解了以下行

$_SERVER['REQUEST_URI'] = preg_replace('|/$|', '', $_SERVER['REQUEST_URI'], 1);

$request = Request::createFromGlobals()之前

【讨论】:

有点老套,但我喜欢。 喜欢!我认为 Symfony 团队应该将此解决方案集成到代码库中。【参考方案6】:

对于新的 SF 版本:

默认情况下,Symfony 路由组件要求参数匹配以下正则表达式路径:[^/]+。这意味着除了/之外的所有字符都是允许的。

您必须通过指定更宽松的正则表达式路径来明确允许 / 成为您的参数的一部分。

YAML:

_hello:
    path:     /hello/username
    defaults:  _controller: AppBundle:Demo:hello 
    requirements:
        username: .+

XML:

<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="_hello" path="/hello/username">
        <default key="_controller">AppBundle:Demo:hello</default>
        <requirement key="username">.+</requirement>
    </route>
</routes>

PHP:

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection = new RouteCollection();
$collection->add('_hello', new Route('/hello/username', array(
    '_controller' => 'AppBundle:Demo:hello',
), array(
    'username' => '.+',
)));

return $collection;

注释:

/**
 * @Route("/hello/username", name="_hello", requirements="username"=".+")
 */
public function helloAction($username)

    // ...

【讨论】:

但是当请求是 /hello/john/ 那么 $username 将是 john/ 并且需要额外的解析。【参考方案7】:

路线:

 remove_trailing_slash:
        path: /url
        defaults:  _controller: AppBundle:Redirecting:removeTrailingSlash 
        requirements:
            url: .*/$
        methods: [GET]

控制器:

// src/AppBundle/Controller/RedirectingController.php
namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class RedirectingController extends Controller

    public function removeTrailingSlashAction(Request $request)
    
        $pathInfo = $request->getPathInfo();
        $requestUri = $request->getRequestUri();

        $url = str_replace($pathInfo, rtrim($pathInfo, ' /'), $requestUri);

        return $this->redirect($url, 301);
    

阅读更多:http://symfony.com/doc/current/routing/redirect_trailing_slash.html

【讨论】:

以上是关于允许没有参数的 Symfony2 路由的尾部斜杠?的主要内容,如果未能解决你的问题,请参考以下文章

react-router 路由中的尾部正斜杠

带有或不带有斜杠的 PHP RegEx

从每个参数中删除尾部斜杠的最简单方法是啥?

URL 中带有斜杠“/”的路由参数

Symfony2 路由:不允许的方法(允许:Method)

如何在Symfony 4.1中禁用尾部斜杠重定向?