迁移到 TYPO3 9+ 后继续重定向旧的 realurl url
Keep redirecting old realurl urls after migrating to TYPO3 9+
我想使用过期url的真实url内存为升级到TYPO3 9+的站点生成301并避免404。
例如,在TYPO3 9之前,获取/my-old-page
被重定向到/my-new-page
,因为/my-old-page
还在真正的url数据库table中。
现在,由于迁移到 TYPO3 9,获取 /my-old-page
会抛出 404.
TYPO3 9 附带了一个升级向导,可以将 realurl pagepath/aliases 转换为 slug,但不会将 realurl 的过期 pagepath/aliases 转换为 sys_redirect
.
保持真实url 重定向记忆的最佳策略是什么:
- 是否将所有过期的 url/alias 迁移到 sys_redirect?这可能会导致很大的 sys_redirect table,以及性能问题
- 运行 在 RedirectHandler 之后搜索过期 url 并在找到时触发 301 的中间件?这将为每个请求进行额外的数据库查询。
- 创建一个 PageNotFoundHandler 来搜索过期的 url 如果找不到页面? TYPO3 只允许每个状态代码有一个 ErrorHandler,所以这可能是一个问题
- 在 .htaccess 中列出重定向
“最佳策略”是指:
- 性能可能很重要(我有超过 10,000 个过期 urls)
- 如果可能,重定向应由编辑器维护(如 sys_redirect)
感谢您的见解!
例如,对于以下内容,我假设您使用 Apache Webserver 并且可以访问 /etc/apache2 下的 Web 服务器配置。
我没有任何数字,但我假设您在网络服务器中处理的重定向比启动 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 [R=307,L]
示例 2 RewriteMap:
/etc/apache2/sites-available/mysite.conf
RewriteEngine on
RewriteMap exactredirects "txt:/etc/apache2/redirects/exactredirects.txt"
RewriteRule "^(.*)$" "${exactredirects:|/404}" [R=307,L]
/etc/apache2/重定向/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:
- 为 404 创建基于
PageErrorHandlerInterface
的页面错误处理程序。检查 URL 的真实网址 table。如果命中,请重定向到新的 URL.
- 如果没有命中,则回到您通常会做的事情,例如显示错误页面。
这有以下优点(对 TYPO3 重定向扩展):
- 它只在 404 上触发,而不是在每个页面上触发。
- 此外,您不必将重定向迁移到 sys_redirects,您可以按原样使用旧的真实网址 table。
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', $queryBuilder->createNamedParameter($languageId, \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;
}
我想使用过期url的真实url内存为升级到TYPO3 9+的站点生成301并避免404。
例如,在TYPO3 9之前,获取/my-old-page
被重定向到/my-new-page
,因为/my-old-page
还在真正的url数据库table中。
现在,由于迁移到 TYPO3 9,获取 /my-old-page
会抛出 404.
TYPO3 9 附带了一个升级向导,可以将 realurl pagepath/aliases 转换为 slug,但不会将 realurl 的过期 pagepath/aliases 转换为 sys_redirect
.
保持真实url 重定向记忆的最佳策略是什么:
- 是否将所有过期的 url/alias 迁移到 sys_redirect?这可能会导致很大的 sys_redirect table,以及性能问题
- 运行 在 RedirectHandler 之后搜索过期 url 并在找到时触发 301 的中间件?这将为每个请求进行额外的数据库查询。
- 创建一个 PageNotFoundHandler 来搜索过期的 url 如果找不到页面? TYPO3 只允许每个状态代码有一个 ErrorHandler,所以这可能是一个问题
- 在 .htaccess 中列出重定向
“最佳策略”是指:
- 性能可能很重要(我有超过 10,000 个过期 urls)
- 如果可能,重定向应由编辑器维护(如 sys_redirect)
感谢您的见解!
例如,对于以下内容,我假设您使用 Apache Webserver 并且可以访问 /etc/apache2 下的 Web 服务器配置。
我没有任何数字,但我假设您在网络服务器中处理的重定向比启动 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 [R=307,L]
示例 2 RewriteMap:
/etc/apache2/sites-available/mysite.conf
RewriteEngine on
RewriteMap exactredirects "txt:/etc/apache2/redirects/exactredirects.txt"
RewriteRule "^(.*)$" "${exactredirects:|/404}" [R=307,L]
/etc/apache2/重定向/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:
- 为 404 创建基于
PageErrorHandlerInterface
的页面错误处理程序。检查 URL 的真实网址 table。如果命中,请重定向到新的 URL. - 如果没有命中,则回到您通常会做的事情,例如显示错误页面。
这有以下优点(对 TYPO3 重定向扩展):
- 它只在 404 上触发,而不是在每个页面上触发。
- 此外,您不必将重定向迁移到 sys_redirects,您可以按原样使用旧的真实网址 table。
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', $queryBuilder->createNamedParameter($languageId, \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;
}