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

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

【问题讨论】:

标签: symfony yaml


【解决方案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/page{trailingSlash}", 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://stackoverflow.com/a/11078348/593957),因为它不会触发外部重定向。

这是一个 yaml 版本:

acme_admin_dashboard:
    pattern:  /{_locale}/admin{trailingSlash}
    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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多