htaccess 重写后,获取变量变得无法访问

htaccess 重写后,获取变量变得无法访问

我正在尝试使用 SEO 友好的 URL,因此我使用 htaccess 重定向到更友好的目标。但是,当我执行这些重定向时,我无法再从新 URL 访问 get 变量,即使我转到旧 URL 时可以获取它们。我特别查看了“writer”行,尽管我已将其余部分包含在上下文中。有什么想法可以解决这个问题吗?

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
RewriteRule ^writer/([0-9a-zA-z_-]+) writer?user=$1 [QSA,L]
RewriteRule ^article/([0-9a-zA-z_-]+)/([0-9a-zA-z_-]+) article?id=$1&title=$2 [QSA,L]

答案1

听起来 MultiViews 可能已启用。由于您writer在 URL 中拥有writer.php(与要重写的文件相同的基本名称),因此您需要确保 MultiViews (mod_negotiation 的一部分) 已禁用,否则 MultiViews 将发出内部子请求writer.php(不带 URL 参数)您的 mod_rewrite 指令能够处理该请求。

在文件顶部.htaccess

Options -MultiViews
RewriteRule ^writer/([0-9a-zA-z_-]+) writer?user=$1 [QSA,L]

您还应该直接重写处理请求的文件。使用上述指令,您可以依赖另一个指令进一步重写请求(在第二次传递期间)以附加必要的文件扩展名。

换句话说:

RewriteRule ^writer/([0-9a-zA-z_-]+) writer.php?user=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]

并更改指令的顺序,以便最后添加文件扩展名的“catch-all”规则。但是,您无法在 中重写为绝对文件系统路径.htaccess,这需要是 URL 路径,因此在 中使用REQUEST_URI而不是REQUEST_FILENAMERewriteRule 代换。 例如:

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !\.php$ %{REQUEST_URI}.php [QSA,L]

但是,根据文件系统结构,REQUEST_FILENAME不一定REQUEST_URI引用相同的 URL 路径。因此,REQUEST_URI状况也一样。例如:

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule !\.php$ %{REQUEST_URI}.php [QSA,L]

您可能还想排除包含任何文件扩展名的请求,例如静态资源(图像、css、js)。目前,每个请求也会有一个(相对昂贵的)文件系统。

总之:

Options -MultiViews

RewriteEngine On

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteRule ^writer/([0-9a-zA-z_-]+) writer.php?user=$1 [QSA,L]
RewriteRule ^article/([0-9a-zA-z_-]+)/([0-9a-zA-z_-]+) article.php?id=$1&title=$2 [QSA,L]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule !\.php$ %{REQUEST_URI}.php [QSA,L]

更新:

.htaccess 位于 public_html 中,而 writer.php 位于 public_html 下名为 users 的文件夹中

如果writer.php位于/users子目录中,那么您显然需要在某处引用该子目录,可以在指令中(替代字符串)本身,或者RewriteBase如果所有被重写的文件都位于这个子目录中,则可以使用指令。

例如:

RewriteRule ^writer/([0-9a-zA-z_-]+) users/writer.php?user=$1 [QSA,L]

由于.htaccess文件位于文档根目录中,因此上述指令假定您正在发出以下形式的请求/writer/abc。如果请求实际上是针对/users/writer/abc,则您需要修改RewriteRule 图案相应地(或将.htaccess文件移动到/users子目录中 - 但你不应该修改代换细绳)。

请注意代换没有前导斜杠(或方案 + 主机名)的字符串(即users/writer.php?user=$1)被视为相对的。它与文件的位置相关.htaccess,除非RewriteBase定义了其他说明。

(由于writer.php最初似乎被调用时没有任何 URL 参数,那么这听起来好像您正在发出表单请求/users/writer/abc?)

相关内容