请求编写.htaccess重写规则:子域名重定向至目录及特定页面
Got it, let’s work through those targeted redirects to complement your existing setup. You’ve already nailed the base rule that sends all traffic from fr.example.com to example.com/fr/—now we just need to layer in specific page rules that take priority over that catch-all.
Critical Rule Order Note
First things first: specific page redirects must come before your general subdomain rule. Apache processes rewrite rules top-to-bottom, so if your catch-all rule is first, it’ll match every request and skip your targeted rules entirely.
Example 1: Redirect a Single Static Page
Suppose your old French about page at fr.example.com/old-about.html now lives at example.com/fr/a-propos. Add this rule above your existing one:
RewriteCond %{HTTP_HOST} ^fr\.example\.com [NC] RewriteRule ^old-about\.html$ http://example.com/fr/a-propos [L,R=301]
^old-about\.html$: Anchors the rule to match exactly that page (no partial matches, so it won’t trigger forfr.example.com/old-about.html?foo=barunless you add theQSAflag to preserve query strings)[NC]: Makes the host match case-insensitive (soFR.example.comalso works)[L,R=301]:Lstops further rule processing once this matches;R=301marks it as a permanent redirect (critical for SEO)
Example 2: Redirect a Dynamic Page with Parameters
If you had a dynamic product page like fr.example.com/product.php?id=123 that’s now at example.com/fr/produits/123, use this:
RewriteCond %{HTTP_HOST} ^fr\.example\.com [NC] RewriteCond %{QUERY_STRING} ^id=([0-9]+)$ RewriteRule ^product\.php$ http://example.com/fr/produits/%1 [L,R=301,QSD]
%{QUERY_STRING} ^id=([0-9]+)$: Captures the numeric product ID from the query string%1: Inserts the captured ID into the new URL path[QSD]: Discards the original query string (since we’ve moved the ID into the path—omit this if you want to keep extra query parameters)
Example 3: Redirect an Entire Directory
If all old blog pages under fr.example.com/blog/ now live at example.com/fr/blogue/, use a rule that preserves the rest of the path:
RewriteCond %{HTTP_HOST} ^fr\.example\.com [NC] RewriteRule ^blog/(.*)$ http://example.com/fr/blogue/$1 [L,R=301,QSA]
(.*): Captures everything after/blog/(likepost-1.htmlorcategory/tech)$1: Replays that captured content in the new path[QSA]: Preserves any query strings from the original request
Full .htaccess Structure
Putting it all together, your file should look like this (specific rules first, then the catch-all):
RewriteEngine On # Targeted specific page redirects RewriteCond %{HTTP_HOST} ^fr\.example\.com [NC] RewriteRule ^old-about\.html$ http://example.com/fr/a-propos [L,R=301] RewriteCond %{HTTP_HOST} ^fr\.example\.com [NC] RewriteCond %{QUERY_STRING} ^id=([0-9]+)$ RewriteRule ^product\.php$ http://example.com/fr/produits/%1 [L,R=301,QSD] RewriteCond %{HTTP_HOST} ^fr\.example\.com [NC] RewriteRule ^blog/(.*)$ http://example.com/fr/blogue/$1 [L,R=301,QSA] # General catch-all redirect for all other pages RewriteCond %{HTTP_HOST} ^fr\.example\.com [NC] RewriteRule (.*) http://example.com/fr/$1 [L,R=301]
Quick Pro Tips
- Always test redirects before deploying! You can check server logs or use browser dev tools to verify the 301 status code and target URL.
- If you have multiple language subdomains (like
es.example.com), you can replicate this pattern by swappingfrwith the appropriate language code.
内容的提问来源于stack exchange,提问作者Cécile Habran

