我需要使用 htaccess 从 url 中删除一个参数
从
http://example.com/page/detail/page.php?name=franco&age=50
到
http://example.com/page/detail/page.php?age=50
我正在使用这个 htaccess:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(.*)&?name=[^&]+&?(.*)$ [NC]
RewriteRule ^/?(.*)$ /$1?%1%2%3 [R=301,L]
但是我有这个结果,我丢失了页面的路径:
http://example.com/page.php?eta=57
答案1
该文件位于与页面相同的文件夹中。
这就是“问题”。在每个目录.htaccess
文件中RewriteRule
图案(即^/?(.*)$
)与 URL 路径匹配减去目录前缀,而不是完整的 URL 路径。换句话说,捕获的 URL 路径只是page.php
,并不是page/detail/page.php
您所期望的那样。
您的指令的编写方式就好像该.htaccess
文件位于您网站的文档根目录中,而不是子目录中。
因为你不是改变URL 路径你可以简单地使用REQUEST_URI
服务器变量来代替代换字符串,其中包含完整的 URL 路径(包括斜杠前缀):
RewriteRule ^ %{REQUEST_URI}?%1%2 [R=302,L]
由于您要匹配每个 URL 路径,并且不需要捕获任何内容,因此您可以简化RewriteRule
图案从^/?(.*)$
到^
。%3
您的示例中的反向引用是多余的(前面的条件模式)。
请注意,这是一个 302(临时)重定向。只有当您确定它正常工作时才将其更改为 301(永久) - 以避免浏览器缓存问题。
您需要在测试之前清除浏览器缓存。
正RewriteCond
则表达式也可以简化:
RewriteCond %{QUERY_STRING} (.*)name=[^&]+&?(.*) [NC]
由于第一个&
是可选的(即&?
),前面的子模式(.*)
无论如何都会使用它(这是必需的)。因此,可以简单地删除第一个&?
。字符串锚定^
和$
也不是必需的(正则表达式是贪婪的默认情况下,无论怎样都会消耗整个字符串)。
NC
仅当可以混合大小写时才严格需要该标志name
,否则应删除该标志。
参数名称始终是第一个参数
如果是这样,那么您就不需要第一个捕获的子模式,并且可以锚定name=
到查询字符串的开头。现在只有一个反向引用(指向name=<value>
URL 参数后的字符串)。
因此,你的指令现在变成:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^name=[^&]+&?(.*) [NC]
RewriteRule ^ %{REQUEST_URI}?%1 [R=302,L]