重定向包含尾斜杠的url
这篇文章的目的是展示如何将一个有尾斜杠的URL重定向到同一个没有尾斜杠的URL(如,/en/blog/
到/en/blog
)。
创建一个能匹配任意包含尾斜杠的URL的控制器(如何有任何query parameters则予以保留),删除尾斜杠并重定向到一个301响应状态码的新URL,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 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);
}
} |
之后,创建一个路由到该控制器,使任意有尾斜杠的URL在访问时都能匹配到该路由。务必把这个路由放到程序最后,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// src/AppBundle/Controller/RedirectingController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class RedirectingController extends Controller
{
/**
* @Route("/{url}", name="remove_trailing_slash",
* requirements={"url" = ".*\/$"}, methods={"GET"})
*/
public function removeTrailingSlashAction(Request $request)
{
// ...
}
} |
1 2 3 4 5 6 |
remove_trailing_slash:
path: /{url}
defaults: { _controller: AppBundle:Redirecting:removeTrailingSlash }
requirements:
url: .*/$
methods: [GET] |
1 2 3 4 5 6 7 |
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing">
<route id="remove_trailing_slash" path="/{url}" methods="GET">
<default key="_controller">AppBundle:Redirecting:removeTrailingSlash</default>
<requirement key="url">.*/$</requirement>
</route>
</routes> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add(
'remove_trailing_slash',
new Route(
'/{url}',
array(
'_controller' => 'AppBundle:Redirecting:removeTrailingSlash',
),
array(
'url' => '.*/$',
),
array(),
'',
array(),
array('GET')
)
); |
重定向一个POST请求并不适用于老的浏览器。在重定向后由于一些原因一个 POST 请求的 302 会发送一个 GET 请求,因此,这里的路由只能匹配 GET 请求。
确保在你的路由配置中,在路由列表的最末端包含此路由。否则,你会危险地把真正在path中拥有尾斜杠的路由(包括 Symfony 的核心路由)给重定向了。