重定向|从旧 URL 转发到新 URL
Redirect|Forward from old URL to new URL
我有一个路由和一个方法以这种方式操纵 URLs:
http://domain.com/combivent?email=WGA1cUtKZi4
现在URL变成了这个:
http://domain.com/?email=WGA1cUtKZi4
但是旧邮件仍然保留旧邮件。我需要将每个 URL 从旧方法重定向到新方法。例如,如果我调用这个 http://domain.com/combivent?email=WGA1cUtKZi4
那么我应该重定向到 http://domain.com/?email=WGA1cUtKZi4
如何在 Symfony2 中实现这个?我可以在路由中使用任何类型的通配符,还是我需要保留这两种方法并在内部处理?这可以在 .htaccess
级别完成吗?有什么建议吗?
这是 .htaccess
的样子:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
# Remove combivent word from the URL when call a brand page
RewriteRule ^combivent?email=([^/]+)$ /?email= [L,QSA,R=301]
RewriteRule .? %{ENV:BASE}/app.php [L]
</IfModule>
此外,此 domain.com
是共享三个域的 VirtualHost 的别名。将 VH 定义视为:
ServerName maindomain.com
ServerAlias domain.com
ServerAlias domain1.com
更新
下面是完整的 .htaccess
定义:
DirectoryIndex app.php
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Remove combivent word from the URL when call a brand page
RewriteCond %{QUERY_STRING} ^email=[^&]+ [NC]
RewriteRule ^combivent/?$ / [L,R=301]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/app.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
RedirectMatch 302 ^/$ /app.php/
</IfModule>
</IfModule>
只需将以下规则添加到您的 .htaccess
文件中:
RewriteEngine On
RewriteRule ^combivent?email=([^/]+)$ /?email= [L,QSA,R=301]
编辑:您需要将其添加到上方以下行:
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/app.php [L]
这条规则有问题:
# Remove combivent word from the URL when call a brand page
RewriteRule ^combivent?email=([^/]+)$ /?email= [L,QSA,R=301]
因为您无法使用 RewriteRule
匹配 QUERY_STRING
。使用 RewriteCond
代替:
# Remove combivent word from the URL when call a brand page
RewriteCond %{QUERY_STRING} ^email=[^&]+ [NC]
RewriteRule (?:^|/)combivent/?$ / [L,R=301]
QUERY_STRING
会自动转运到nee目标
完整的.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Remove combivent word from the URL when call a brand page
RewriteCond %{QUERY_STRING} ^email=[^&]+ [NC]
RewriteRule (?:^|/)combivent/?$ / [L,R=302,NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/app.php [L]
另外请确保在测试之前清除浏览器缓存。
与其深入研究 .htaccess
,不如将旧路由重定向到路由中的新路由。
new_route:
path: /
defaults: ...
old_route:
path: /combivent
defaults:
_controller: FrameworkBundle:Redirect:redirect
route: new_route
permanent: true
当您使用注释时,您只需要为新路线命名或找出生成的名称并在您的 "old_route" 定义中使用它。
更新了您的实际设置
PDOneBundle/Resources/config/routing.yml
pdone:
resource: "@PDOneBundle/Controller/"
type: annotation
prefix: /
# add this
combivent:
path: /combivent
defaults:
_controller: FrameworkBundle:Redirect:redirect
route: brand
permanent: true
PDOneBundle\Controller\BrandPageController
class BrandPageController extends Controller
{
/**
* @param Request $request
*
* @return array
* @Route("/combivent", name="combivent") <!-- remove this
* @Route("/", name="brand")
* @Method("GET")
* @Template()
*/
public function indexAction(Request $request)
{
...
}
}
我有一个路由和一个方法以这种方式操纵 URLs:
http://domain.com/combivent?email=WGA1cUtKZi4
现在URL变成了这个:
http://domain.com/?email=WGA1cUtKZi4
但是旧邮件仍然保留旧邮件。我需要将每个 URL 从旧方法重定向到新方法。例如,如果我调用这个 http://domain.com/combivent?email=WGA1cUtKZi4
那么我应该重定向到 http://domain.com/?email=WGA1cUtKZi4
如何在 Symfony2 中实现这个?我可以在路由中使用任何类型的通配符,还是我需要保留这两种方法并在内部处理?这可以在 .htaccess
级别完成吗?有什么建议吗?
这是 .htaccess
的样子:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
# Remove combivent word from the URL when call a brand page
RewriteRule ^combivent?email=([^/]+)$ /?email= [L,QSA,R=301]
RewriteRule .? %{ENV:BASE}/app.php [L]
</IfModule>
此外,此 domain.com
是共享三个域的 VirtualHost 的别名。将 VH 定义视为:
ServerName maindomain.com
ServerAlias domain.com
ServerAlias domain1.com
更新
下面是完整的 .htaccess
定义:
DirectoryIndex app.php
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Remove combivent word from the URL when call a brand page
RewriteCond %{QUERY_STRING} ^email=[^&]+ [NC]
RewriteRule ^combivent/?$ / [L,R=301]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/app.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
RedirectMatch 302 ^/$ /app.php/
</IfModule>
</IfModule>
只需将以下规则添加到您的 .htaccess
文件中:
RewriteEngine On
RewriteRule ^combivent?email=([^/]+)$ /?email= [L,QSA,R=301]
编辑:您需要将其添加到上方以下行:
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/app.php [L]
这条规则有问题:
# Remove combivent word from the URL when call a brand page
RewriteRule ^combivent?email=([^/]+)$ /?email= [L,QSA,R=301]
因为您无法使用 RewriteRule
匹配 QUERY_STRING
。使用 RewriteCond
代替:
# Remove combivent word from the URL when call a brand page
RewriteCond %{QUERY_STRING} ^email=[^&]+ [NC]
RewriteRule (?:^|/)combivent/?$ / [L,R=301]
QUERY_STRING
会自动转运到nee目标
完整的.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Remove combivent word from the URL when call a brand page
RewriteCond %{QUERY_STRING} ^email=[^&]+ [NC]
RewriteRule (?:^|/)combivent/?$ / [L,R=302,NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/app.php [L]
另外请确保在测试之前清除浏览器缓存。
与其深入研究 .htaccess
,不如将旧路由重定向到路由中的新路由。
new_route:
path: /
defaults: ...
old_route:
path: /combivent
defaults:
_controller: FrameworkBundle:Redirect:redirect
route: new_route
permanent: true
当您使用注释时,您只需要为新路线命名或找出生成的名称并在您的 "old_route" 定义中使用它。
更新了您的实际设置
PDOneBundle/Resources/config/routing.yml
pdone:
resource: "@PDOneBundle/Controller/"
type: annotation
prefix: /
# add this
combivent:
path: /combivent
defaults:
_controller: FrameworkBundle:Redirect:redirect
route: brand
permanent: true
PDOneBundle\Controller\BrandPageController
class BrandPageController extends Controller
{
/**
* @param Request $request
*
* @return array
* @Route("/combivent", name="combivent") <!-- remove this
* @Route("/", name="brand")
* @Method("GET")
* @Template()
*/
public function indexAction(Request $request)
{
...
}
}