You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.htaccess语言路径重写问题:本地正常线上404

.htaccess语言路径重写线上服务器404问题

问题现象

本地环境中,带语言路径的URL(如http://spa.domain.loc/en/about-us.html)可正常匹配语言规则并跳转至对应控制器;但在线上服务器访问https://spa.domain.ro/en/rezervare-spa.html时出现404错误,语言匹配规则未触发。

需求

通过/en/这类路径传递lang参数到PHP(实际对应请求为https://spa.domain.ro/rezervare-spa.html?lang=en),且用户看不到该参数。

当前.htaccess配置

RewriteEngine On

# REWRITE IF HAVE LANGUAGE /en/ path
RewriteBase /

# Force trailing slash on language code
RewriteRule ^(en)$ $1/ [R=301,L]

# Default to Romanian (other languages example path. /en/<anything>)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/(.*)
#RewriteRule !^(en/|/)(.*) %1 [R,L]

# Route language URLs
RewriteRule ^([a-zA-Z]{2})/(.*) $2?lang=$1 [QSA,L]

# END LANGUAGE

# Security Fixes
RewriteRule ^\.htaccess$ - [F,L]
RewriteRule ^_scripts/ - [F,L]
RewriteRule ^_sql/ - [F,L]
RewriteRule ^_logos/ - [F,L]
RewriteRule ^etc/live\.2CQA\-VZRG\-6AVL\-PB0Q\-1KJP\.public\.cer$ - [F,L]
RewriteRule ^etc/live\.2CQA\-VZRG\-6AVL\-PB0Q\-1KJPprivate\.key$ - [F,L]
RewriteRule ^etc/config\.php$ - [F,L]
RewriteRule ^etc/config-index\.php$ - [F,L]
RewriteRule ^etc/config-admin\.php$ - [F,L]
RewriteRule ^etc/init\.php$ - [F,L]
RewriteRule ^etc_online/config\.php$ - [F,L]
RewriteRule ^etc_online/config-index\.php$ - [F,L]
RewriteRule ^etc_online/config-admin\.php$ - [F,L]
RewriteRule ^etc_online/init\.php$ - [F,L]
RewriteRule ^tmp/ - [F,L]
RewriteRule ^wpub/\.htaccess$ - [F,L]
RewriteRule ^wpub/\#wpub$ - [F,L]
RewriteRule ^\#db/ - [F,L]

##### Temporary maintenance ; must be 302 as 307 does not behave correctly (if the file maintenance.html exists in the web root)

RewriteCond %{HTTP_HOST} ^(.*)\.
RewriteCond /maintenance.html !-f
RewriteRule ^maintenance.html$ / [L,R=301]

RewriteCond %{HTTPS}            off
RewriteCond %{HTTP_HOST}        ^(?:(spa)\.)?(domain\.ro)$

RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Redirect to www if no sub-domain (Ex: http(s)://domain.ext -> http(s)://www.domain.ext)
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://spa.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Homepage Rules
#RewriteCond        %{HTTP_HOST} ^(www)\.
RewriteRule         ^$   index.php?page=frontend.homepage [QSA,L]

# Custom Rules: old-rules
RedirectMatch 301 ^/about\.html$                                /about-us.html
RedirectMatch 301 ^/rates\.php$                                 /rates.html
RedirectMatch 301 ^/news\.php$                                  /news.html
RedirectMatch 301 ^/location\.php$                              /location.html
RedirectMatch 301 ^/gallery\.php$                               /gallery.html
RedirectMatch 301 ^/privacy-policy\.php$                        /privacy-policy.html
RedirectMatch 301 ^/contact\.php$                               /contact.html

# RULES MOBILPAY PAYMENT
    # Custom Rules: return-mobilpay
    RewriteCond         %{REQUEST_FILENAME} !-f
    RewriteCond         %{REQUEST_FILENAME} !-d
    RewriteRule         ^return-mobilpay\.html$                                         index.php?page=frontend.mobilpay-return [QSA,L]

    # Custom Rules: confirm-mobilpay
    RewriteCond         %{REQUEST_FILENAME} !-f
    RewriteCond         %{REQUEST_FILENAME} !-d
    RewriteRule         ^confirm-mobilpay\.html$                                        index.php?page=frontend.mobilpay-confirm [QSA,L]

# RULES VIVA WALLET PAYMENT
    # Custom Rules: return-vivawallet
    RewriteCond         %{REQUEST_FILENAME} !-f
    RewriteCond         %{REQUEST_FILENAME} !-d
    RewriteRule         ^return-vivawallet\.html$                                       index.php?page=frontend.vivawallet-return [QSA,L]

    # Custom Rules: confirm-vivawallet
    RewriteCond         %{REQUEST_FILENAME} !-f
    RewriteCond         %{REQUEST_FILENAME} !-d
    RewriteRule         ^confirm-vivawallet\.html$                                      index.php?page=frontend.vivawallet-confirm [QSA,L]

# Custom Rules:
#RewriteCond        %{REQUEST_FILENAME} !-f
#RewriteCond        %{REQUEST_FILENAME} !-d
#RewriteRule        ^rezervare-bungalow\.html$                                      index.php?page=frontend.rezervare-camera&roomid=3 [QSA,L]

# Custom Rules:
RewriteCond         %{REQUEST_FILENAME} !-f
RewriteCond         %{REQUEST_FILENAME} !-d
RewriteRule         ^offers\.html$                                                  index.php?page=frontend.offers-view [QSA,L]

### Sitemap XML Index
RewriteCond         %{REQUEST_FILENAME} !-f
RewriteCond         %{REQUEST_FILENAME} !-d
RewriteRule         ^sitemap\.xml$                                                  /index.php?page=frontend.sitemap-sdom-idx [QSA,L]
### Sitemap XML Content
RewriteCond         %{REQUEST_FILENAME} !-f
RewriteCond         %{REQUEST_FILENAME} !-d
RewriteRule         ^sitemap-content\.xml$                                          /index.php?page=frontend.sitemap-sdom-content [QSA,L]
###
# Custom Rules: backend
RewriteCond         %{REQUEST_FILENAME} !-f
RewriteCond         %{REQUEST_FILENAME} !-d
RewriteRule         ^backend.(.*)\.html$                                        admin.php?page=backend-new.$1 [QSA,L]

# General rewrite rules: map controller name to something else
RewriteCond         %{REQUEST_FILENAME} !-f
RewriteCond         %{REQUEST_FILENAME} !-d
RewriteRule         ^(.*)\.(html|stml|json|xml|rss|csv|txt|png|gif|jpg|pdf|webp)$       index.php?page=$1 [QSA,L]

ErrorDocument 400 /index.php?page=frontend.400
ErrorDocument 404 /index.php?page=frontend.404

问题分析与修复方案

线上服务器出现404的核心原因是语言规则位置靠后,被后续带[L]标记的HTTPS/域名跳转规则截断。本地环境无强制跳转,规则能正常执行;但线上请求先被跳转规则终止处理,语言规则根本没机会触发。

修复步骤

  1. 调整规则顺序:将语言重写规则移到所有跳转规则(HTTPS、域名跳转、维护页跳转)之前,确保语言路径先被解析。
  2. 优化语言规则条件:添加文件/目录存在判断,避免真实存在的资源被误改写。
  3. 保留跳转时的语言路径:现有跳转规则已通过%{REQUEST_URI}保留完整路径,无需额外修改。

修正后的核心规则片段

RewriteEngine On
RewriteBase /

# REWRITE IF HAVE LANGUAGE /en/ path
# Force trailing slash on language code
RewriteRule ^(en)$ $1/ [R=301,L]

# Route language URLs - 先处理语言路径,添加文件/目录判断
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-zA-Z]{2})/(.*) $2?lang=$1 [QSA,L]
# END LANGUAGE

# 之后放置所有跳转、安全、路由规则
##### Temporary maintenance ; must be 302 as 307 does not behave correctly (if the file maintenance.html exists in the web root)
RewriteCond %{HTTP_HOST} ^(.*)\.
RewriteCond /maintenance.html !-f
RewriteRule ^maintenance.html$ / [L,R=301]

# HTTPS强制跳转
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(?:(spa)\.)?(domain\.ro)$
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# 子域名跳转
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://spa.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# 其余规则保持不变...

额外检查项

  • 确认线上服务器mod_rewrite模块已启用。
  • 检查服务器AllowOverride配置是否为All,确保.htaccess规则生效。
  • 清除浏览器缓存,避免旧301跳转缓存干扰测试。

内容的提问来源于stack exchange,提问作者BoBiTza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 19:53:14