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

Apache Rewrite规则问题:URL中%23转#后路径缺失如何修复?

Apache Rewrite规则修复:保留完整路径将%23转换为#

问题

需要把URL domain.xyz/xyz/wtc/id%23name 重定向为 domain.xyz/xyz/wtc/id#name,但当前最后一条Rewrite规则执行后,URL丢失了/xyz前缀,变成domain.xyz/wtc/id#name。

当前使用的Rewrite规则:

# 如果目录或文件存在,直接访问
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 否则转发到index.php
RewriteRule . index.php

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php(.*) [NC]
RewriteRule ^(.*)index\.php(.*)$ http://%{HTTP_HOST}$1/$2 [R=301,L,NE]

RewriteRule ^(.*#.*) /$1 [R,NE]

原因

最后一条规则的问题在于:Apache会自动将%23解码为#,而#属于URL片段,Rewrite规则默认只匹配#之前的路径部分,导致$1无法捕获包含/xyz的完整原始路径;同时直接用/$1会错误截断路径前缀。

解决方案

利用THE_REQUEST变量获取浏览器发送的原始请求行(该变量不会被之前的Rewrite规则修改,且保留未解码的%23),调整后的规则如下:

# 处理%23转#的重定向,保留完整路径
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(/[^?\s]*%23[^?\s]*) [NC]
RewriteRule ^ http://%{HTTP_HOST}%1 [R=302,L,NE]

# 如果目录或文件存在,直接访问
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 否则转发到index.php
RewriteRule . index.php

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php(.*) [NC]
RewriteRule ^(.*)index\.php(.*)$ http://%{HTTP_HOST}$1/$2 [R=301,L,NE]

关键说明

  1. 规则顺序:把处理%23的规则放在最前面,确保请求被转发到index.php前完成重定向。
  2. THE_REQUEST变量:(/[^?\s]*%23[^?\s]*)捕获从根目录开始的完整原始路径(包含%23),保证/xyz不会丢失。
  3. NE标志:禁止Apache对%23二次编码,使其直接转换为#。
  4. 重定向类型:先用R=302临时重定向测试,确认结果符合预期后,再改为R=301永久重定向。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 09:40:37