通过.htaccess重定向旧格式URL以避免404错误
问题描述
我将网站的永久链接(permalink)从/index.php/year/month/postName格式修改为/postName格式后,大量外部旧链接访问时出现404错误。
想通过.htaccess将/index.php/year/month/postName的请求重定向到/postName以避免流量流失,但尝试以下代码后问题仍未解决:
RedirectMatch 301 ^/index\.php/([0-9]+)/([0-9]+)/(.*)$ https://www.example.com/$3
替换成$4也无效。
我的.htaccess完整代码如下:
RewriteEngine On AcceptPathInfo On RewriteRule ^index\.php/\d{4}/\d\d/([^/]*) https://www.example.com/$1 [R=301,L] <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # BEGIN WpFastestCache <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{HTTP_HOST} ^example.com RewriteRule ^(.*)$ http\:\/\/www\.example\.com\/$1 [R=301,L] # Start WPFC Exclude # End WPFC Exclude # Start_WPFC_Exclude_Admin_Cookie RewriteCond %{HTTP:Cookie} !wordpress_logged_in_[^\=]+\=El\sCorregidor|hystoriador # End_WPFC_Exclude_Admin_Cookie RewriteCond %{HTTP_HOST} ^www.example.com RewriteCond %{HTTP_USER_AGENT} !(facebookexternalhit|WhatsApp|Mediatoolkitbot) RewriteCond %{HTTP_USER_AGENT} !(WP\sFastest\sCache\sPreload(\siPhone\sMobile)?\s*Bot) RewriteCond %{REQUEST_METHOD} !POST RewriteCond %{HTTPS} !=on RewriteCond %{REQUEST_URI} !(\/){2}$ RewriteCond %{REQUEST_URI} \/$ RewriteCond %{QUERY_STRING} !.+ RewriteCond %{HTTP:Cookie} !comment_author_ RewriteCond %{HTTP:Cookie} !woocommerce_items_in_cart RewriteCond %{HTTP:Cookie} !safirmobilswitcher=mobil RewriteCond %{HTTP:Profile} !^[a-z0-9\"]+ [NC] RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/all/$1/index.html -f [or] RewriteCond /var/www/vhosts/example.com/httpdocs/wp-content/cache/all/$1/index.html -f RewriteRule ^(.*) "/wp-content/cache/all/$1/index.html" [L] </IfModule> <FilesMatch "index\.(html|htm)$"> AddDefaultCharset UTF-8 <ifModule mod_headers.c> FileETag None Header unset ETag Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires "Mon, 29 Oct 1923 20:30:00 GMT" </ifModule> </FilesMatch> # BEGIN W3TC Page Cache core <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{HTTP:Accept-Encoding} gzip RewriteRule .* - [E=W3TC_ENC:_gzip] RewriteCond %{HTTP_COOKIE} w3tc_preview [NC] RewriteRule .* - [E=W3TC_PREVIEW:_preview] RewriteCond %{REQUEST_METHOD} !=POST RewriteCond %{QUERY_STRING} ="" RewriteCond %{REQUEST_URI} \/$ RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|w3tc_logged_out|wordpress_logged_in|wptouch_switch_toggle) [NC] RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" -f RewriteRule .* "/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" [L] </IfModule> # END W3TC Page Cache core # BEGIN GZIP <ifmodule mod_deflate.c> AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript </ifmodule> # END GZIP # Con especificamos cache <IfModule mod_expires.c> ExpiresActive On ExpiresDefault "access plus 10 days" ExpiresByType text/css "access plus 1 week" ExpiresByType text/plain "access plus 1 week" ExpiresByType image/gif "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" ExpiresByType image/x-icon "access plus 3 months" ExpiresByType application/x-javascript "access plus 1 month" ExpiresByType application/javascript "access plus 1 week" ExpiresByType text/javascript "access plus 1 week" ExpiresByType application/x-icon "access plus 3 months" </IfModule> # FIN Options +FollowSymLinks
解决方案
你的重定向规则无效的核心原因是规则位置错误,请求被后续的WordPress核心规则或缓存规则优先处理,轮不到重定向生效。另外RedirectMatch与mod_rewrite规则混用容易出现优先级冲突,建议统一使用mod_rewrite规则。
具体修改步骤
- 删除你当前写的
RewriteRule ^index\.php/\d{4}/\d\d/([^/]*) https://www.example.com/$1 [R=301,L]以及之前尝试的RedirectMatch代码。 - 在
.htaccess文件的最顶部添加以下规则:
RewriteEngine On RewriteRule ^index\.php/\d{4}/\d{1,2}/([^/]+)$ /$1 [R=301,L,NC]
规则说明
^index\.php/\d{4}/\d{1,2}/:精准匹配开头为/index.php/+4位年份+1-2位月份的路径([^/]+):捕获postName部分(直到下一个斜杠为止,避免匹配多余内容)/$1:用相对路径重定向到新的永久链接,避免硬编码域名,方便后续维护[R=301,L,NC]:R=301表示永久重定向(对SEO友好),L表示执行完这条规则后停止后续规则处理,NC表示不区分大小写
测试注意事项
- 测试前务必清除浏览器缓存,因为301重定向会被浏览器缓存,旧缓存会影响测试结果
- 如果你的postName包含斜杠(特殊情况),可把
([^/]+)替换为(.*),但要注意避免和其他路径冲突 - 确认服务器已开启mod_rewrite模块(WordPress环境通常默认开启)
内容的提问来源于stack exchange,提问作者damargon
相关产品推荐
相关产品推荐

