问题描述
我想使用过期url的realurl内存为升级到TYPO3 9+的网站生成301,并避免404。
例如,在TYPO3 9之前,由于/my-old-page
仍在realurl数据库表中,因此将获取/my-new-page
重定向到/my-old-page
。
现在,自从迁移到TYPO3 9以来,获取/my-old-page
会抛出404。
TYPO3 9附带了一个升级向导,该向导可将realurl页面路径/别名转换为段,但不会将realurl的过期页面路径/别名转换为sys_redirect
。
保留重定向的realurl记忆的最佳策略是什么:
- 是否将所有过期的URL /别名迁移到sys_redirect?这可能会导致sys_redirect表很大,并出现性能问题
- 在RedirectHandler之后运行中间件,以搜索过期的url并触发301(如果找到)?这将为每个请求进行额外的数据库查询。
- 创建一个PageNotFoundHandler,如果找不到页面,它会搜索过期的URL? TYPO3每个状态码只允许一个ErrorHandler,因此可能是个问题
- 在.htaccess中列出重定向
我所说的“最佳策略”:
感谢您的见解!
解决方法
对于以下情况,我假设您使用的是Apache Webserver,例如,可以访问/ etc / apache2下的Webserver配置。
我没有任何数字,但是我认为您在网络服务器中处理的重定向比启动PHP和TYPO3更有效。缺点是重定向也要针对静态资产进行评估(除非在其他地方处理,例如CDN)。同样,这不能由编辑者维护。但是,例如,如果要从realurl进行迁移,则可以通过Apache使用此解决方案作为临时解决方案,过一会儿再取下来。
但是,如果您有大量的重定向,这将变得难以维护且非常难看。
这些年来,我看到的站点经常积累了重定向,经常愉快地混合使用RewriteRule,Redirect(或重定向),RedirectMatch和RewriteCond来进行很好的评估。为了保持整洁,我有2条建议(在我维护的网站中都使用过):
-
在配置管理系统(例如angular,SiteStack)中维护重定向。不要在其中编写重定向语句,而只需添加URL,然后让您的状态(或CM称为它们的状态)为您编写状态
-
使用RewriteMap和一个由URL组成的文件。
对于这两种解决方案,通常都具有(至少)两种类型的重定向:
- 完全重定向,例如您想将/ abc / def重定向到/ new / def,但不重定向例如/ abc / def / subpage
- 正则表达式或通配符重定向,例如您要将/ abc / *重定向到/ new / *
两者都可以使用适当的RewriteRule语句进行处理,但是它们看起来有所不同。对于解决方案1和2,您需要分别处理。
示例1(正则表达式重定向):
RewriteRule /?abc/(.*)? /new$1 [R=307,L]
示例2 RewriteMap:
/etc/apache2/sites-available/mysite.conf
RewriteEngine on
RewriteMap exactredirects "txt:/etc/apache2/redirects/exactredirects.txt"
RewriteRule "^(.*)$" "${exactredirects:$1|/404}" [R=307,L]
/etc/apache2/redirects/exactredirects.txt:
/abc.txt /def.txt
建议:
- 将Apache配置和重定向文件置于版本控制中
- 小心301(永久)。永久重定向表示永久重定向。由于这是在客户端中处理的,因此您无法撤消此操作。如果确定,请仅使用301。
- 您经常会看到使用.htaccess的建议。您可以使用它而不是将其放在Apache配置中。但是,如果您完全控制Apache配置,则不需要.htaccess,并且文档建议完全不要使用.htaccess,除非您需要它。有一个很大的缺点(除了性能方面的考虑):如果您在.htaccess中犯了一个错误,您可以将服务器断开。如果您在Apache配置中进行了更改,则可以执行
service apache2 reload
(由于错误而中止)或apachectl configtest
。 (甚至更好的是,CM在执行状态之前为您执行此操作。) - 关于使用
RewriteRule
与Redirect
的比较:您可以同时使用和和它的变体(例如RedirectMatch)做很多事情,但是RewriteRule通常更强大,而另一个则可能更快。理想情况下,使用其中一个。另请参见"When not to use mod_rewrite"。
我的第二个解决方案(我正在使用-经过稍微修改-在生产中)是使用TYPO3:
- 基于
PageErrorHandlerInterface
为404创建页面错误处理程序。检入realurl表中的URL。如果有成功,请重定向到新URL。 - 如果没有成功,请退回您通常要执行的操作,例如显示错误页面。
这具有以下优点(对TYPO3重定向扩展):
- 仅在404上启动,而不是在每个页面上启动。
- 此外,您不必将重定向迁移到sys_redirects,可以按原样使用旧的realurl表。
Repository \ PathMappingRepository:
public function findPageidForPathFromRealurl(string $path,int $languageId) : int
{
$path = ltrim($path,'/');
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_realurl_pathdata');
$uid = $queryBuilder->select('tx_realurl_pathdata.page_id')
->from('tx_realurl_pathdata')
->join(
'tx_realurl_pathdata','pages','p',$queryBuilder->expr()->eq('tx_realurl_pathdata.page_id',$queryBuilder->quoteIdentifier('p.uid'))
)
->where(
$queryBuilder->expr()->like('tx_realurl_pathdata.pagepath',$queryBuilder->createNamedParameter($path)),$queryBuilder->expr()->eq('tx_realurl_pathdata.language_id',$queryBuilder->createNamedParameter($languageId,\PDO::PARAM_INT)),$queryBuilder->expr()->eq('p.sys_language_uid',\PDO::PARAM_INT))
)
->orderBy('tx_realurl_pathdata.uid','DESC')
->execute()
->fetchColumn(0);
$this->logger->debug("findPageidForPathFromRealurl: path=$path language=$languageId returns $uid");
return (int)$uid;
}