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/testxx.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 参数?的主要内容,如果未能解决你的问题,请参考以下文章

iis里URL重写重定向,http做301重定向https

如何在 .Htaccess 中禁用/不允许共享主机 RewriteLog 时,在 Apache 2 中模拟和测试 URL 重写规则?

如何在apache中重写url

如何在 apache 上用 mod_rewrite 重写我的 url?

Apache 重写 - 在 PHP 中获取原始 URL

URL重写会删除网址结尾