为什么 Apache RewriteRule 对待“&”和“?”的方式相同
Why Apache RewriteRule treats the same way with '&' and '?'
我正在尝试为我的 Apache 网络服务器中的“.htaccess”文件编写自定义重写规则。
主要思想是处理以下形式的请求:
example.com/foo
到 www_root 中的 'index.php' 文件:
example.com/index.php?queryString1=foo
众所周知,这很容易做到。只需将以下行添加到“.htaccess”文件即可:
RewriteEngine on
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteCond %{REQUEST_URI} !-l
RewriteRule ^(.*)$ index.php?queryString1= [QSA,L]
但问题是当我们想在请求中添加另一个查询字符串时,例如如下:
example.com/foo?queryString2=bar&queryString3=baz
出乎我的意料,下面的URL也是如此:
example.com/foo&queryString2=bar&queryString3=baz
我不想执行第二种情况(其中第二个查询字符串以“&”开头)。
此外,如果您在 'index.php' 文件中写入:
<?php echo '<pre>'.print_r($_SERVER['QUERY_STRING'], TRUE).'</pre>'; ?>
那么,URL(example.com/foo?queryString2=bar&queryString3=baz
和 example.com/foo&queryString2=bar&queryString3=baz
)的输出将是唯一的:
queryString1=foo&queryString2=bar&queryString3=baz
任何人都可以解释我在“.htaccess”文件中的代码有什么问题吗?谢谢。
经过上面的讨论,apache2 不处理 & 和 ?以同样的方式。 “?”是 URL 与 QUERY_STRING 的分隔符,但 & 是作为 URL 的一部分的普通字符,由 apache2 RewriteRule 匹配。
在 https://www.example.com/URL?QUERY_STRING, URL is only matched by RewriteRule in .htaccess file, it's the string after the hostname and port if given, and before the query string ref. 的模式中,没有前导斜线 /.
小心,在 apache2 配置文件 vhosts.conf 或类似文件中,当 apache2 服务器启动时阅读,RewriteRule mathches against /URL
字符串(是的,带前导斜线)。
OP的案例只是一个偶然,并非普遍规律。如果 & 涉及 URL:
,我已经通过触发 404 Not Found
错误来测试这个解决方案
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([^&]*)$ index.php?queryString1= [QSA,L]
example.com/foo&queryString2=bar&queryString3=baz
将产生 404 错误。
%{REQUEST_FILENAME}
优于 %{REQUEST_URI}
.
字符范围[^&]表示除&以外的任意字符。使用正则表达式 ^([^&]*)$,我们 select 一个不包含 & 的字符串,从以 ^ 表示的开头到以 $ 表示的结尾,因此 & 无符号。
我正在尝试为我的 Apache 网络服务器中的“.htaccess”文件编写自定义重写规则。
主要思想是处理以下形式的请求:
example.com/foo
到 www_root 中的 'index.php' 文件:
example.com/index.php?queryString1=foo
众所周知,这很容易做到。只需将以下行添加到“.htaccess”文件即可:
RewriteEngine on
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteCond %{REQUEST_URI} !-l
RewriteRule ^(.*)$ index.php?queryString1= [QSA,L]
但问题是当我们想在请求中添加另一个查询字符串时,例如如下:
example.com/foo?queryString2=bar&queryString3=baz
出乎我的意料,下面的URL也是如此:
example.com/foo&queryString2=bar&queryString3=baz
我不想执行第二种情况(其中第二个查询字符串以“&”开头)。 此外,如果您在 'index.php' 文件中写入:
<?php echo '<pre>'.print_r($_SERVER['QUERY_STRING'], TRUE).'</pre>'; ?>
那么,URL(example.com/foo?queryString2=bar&queryString3=baz
和 example.com/foo&queryString2=bar&queryString3=baz
)的输出将是唯一的:
queryString1=foo&queryString2=bar&queryString3=baz
任何人都可以解释我在“.htaccess”文件中的代码有什么问题吗?谢谢。
经过上面的讨论,apache2 不处理 & 和 ?以同样的方式。 “?”是 URL 与 QUERY_STRING 的分隔符,但 & 是作为 URL 的一部分的普通字符,由 apache2 RewriteRule 匹配。
在 https://www.example.com/URL?QUERY_STRING, URL is only matched by RewriteRule in .htaccess file, it's the string after the hostname and port if given, and before the query string ref. 的模式中,没有前导斜线 /.
小心,在 apache2 配置文件 vhosts.conf 或类似文件中,当 apache2 服务器启动时阅读,RewriteRule mathches against /URL
字符串(是的,带前导斜线)。
OP的案例只是一个偶然,并非普遍规律。如果 & 涉及 URL:
,我已经通过触发404 Not Found
错误来测试这个解决方案
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([^&]*)$ index.php?queryString1= [QSA,L]
example.com/foo&queryString2=bar&queryString3=baz
将产生 404 错误。
%{REQUEST_FILENAME}
优于 %{REQUEST_URI}
.
字符范围[^&]表示除&以外的任意字符。使用正则表达式 ^([^&]*)$,我们 select 一个不包含 & 的字符串,从以 ^ 表示的开头到以 $ 表示的结尾,因此 & 无符号。