Apache 重写:如何避免在省略 url 结尾斜杠时显示 url 参数?
Posted
技术标签:
【中文标题】Apache 重写:如何避免在省略 url 结尾斜杠时显示 url 参数?【英文标题】:Apache rewrite : how avoid to display url parameter when the url final slash is omitted? 【发布时间】:2015-12-31 14:16:11 【问题描述】:在我的域的 .htacess 中,我必须将子域指向域的第一个 GET 参数。子域代表语言(例如 en.、fr 等...)。 为了达到这个目的,这里重写.htaccess中的代码:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %HTTP_HOST ^(.*)\.example\.com$ [NC]
RewriteRule ^(.*)$ $1?lang=%1 [NC,L]
我创建了一个名为test
的目录。该目录只包含 index.html 文件。
所以当你在浏览器的网址栏中输入en.example.com/test/
,
重写代码有效。
但是如果你输入en.example.com/test
没有最后的斜线,它会重定向到en.example.com/test/?lang=en
=> 这是一个问题。
那么你有什么改正的想法吗?
在此先感谢您。
【问题讨论】:
参见here '尾斜线问题'。它适用于 Apache 2.0,但仍适用于 2.4。 谢谢,但我在我的代码中尝试了它:RewriteCond %HTTP_HOST ^(.*)\.example\.com$ [NC] RewriteRule ^(.*)$ $1?lang=%1 [NC] RewriteCond %REQUEST_FILENAME -d RewriteRule ^(.+[^/])$ $1/ [R]
=> 它不起作用。
您需要将新规则放在您已有的规则之前。
你是这个意思吗? : RewriteCond %REQUEST_FILENAME -d RewriteRule ^(.+[^/])$ $1/ [R] RewriteCond %HTTP_HOST ^(.*)\.example\.com$ [NC] RewriteRule ^(.*)$ $1?lang=%1 [NC,L]
=> 又不行了
按照你原来的规则,如果你输入en.example.com/test/
(带斜线),它是否也会重定向到en.example.com/test/?lang=en
?
【参考方案1】:
当指定xx.example.com/test/
时,内部重定向
发生在xx.example.com/test/?lang=xx
。客户端永远不会看到?lang=xx
。
但是,当指定xx.example.com/test
时,其中test
是一个目录,
mod_dir
介入并将 URL 重写为 xx.example.com/test/
,但在
这样?lang=xx
重定向的重写规则就会公开,
让客户看到 xx.example.com/test/?lang=xx
作为 URL - 这是不需要的。
为了保持 '?lang=' 重定向本地(对客户端隐藏) 将其放在 .htaccess 中,在原始重写规则之前:
RewriteCond %REQUEST_FILENAME -d
RewriteRule ^(.+[^/])$ $1/ [R,L]
条件检查请求的文件名是否为目录,
并且该规则强制客户端重定向[R]
,因此请求xx.example.com/test
的客户端将被重定向到xx.example.com/test/
。
然而,关键是[L]
,它使这条规则成为最后一条,阻止执行以下规则。如果没有此 L
标志,则从 xx.example.com/test
到 xx.example.com/test/?lang=xx
的整个重定向都会公开。
在客户端被强制重定向到带有终止 /
的正确 URL 后,执行添加 lang
GET 参数的内部重定向的重写规则将正常执行。
这是整个 .htaccess:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %REQUEST_FILENAME -d
RewriteRule ^(.+[^/])$ $1/ [R,L]
RewriteCond %HTTP_HOST ^(.*)\.example\.com$ [NC]
RewriteRule ^(.*)$ $1?lang=%1 [NC,L]
然而,还有另一种方法可以在不使用 Apache 配置和内部重定向的情况下实现这一点,那就是检查 $_SERVER['SERVER_NAME']
:
<?php
list( $lang ) = explode('.', $_REQUEST['SERVER_NAME'] );
【讨论】:
我想点击+1.000.000,但是按钮最多为1。非常(非常)非常感谢!L
标志是必要的,多亏了你,它才能完美运行。但是,你的 php 技巧是天才和最好的方法!!!以上是关于Apache 重写:如何避免在省略 url 结尾斜杠时显示 url 参数?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 .Htaccess 中禁用/不允许共享主机 RewriteLog 时,在 Apache 2 中模拟和测试 URL 重写规则?