使用.htaccess从URL中删除文件扩展名和变量。

3

我知道这个问题已经被问过很多次了,但无论我尝试什么方法,我的代码仍然不能正常运行。我有一个 .htaccess 文件,并且我想将我的代码从以下位置重定向:

example.com/news/articles.php?id=21&artName=Hello-World

到这个:

example.com/news/articles/21/Hello-World

目前我在我的 .htaccess 文件中有这段代码:

Options -MultiViews
RewriteEngine On

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

RewriteRule ^news/articles/([\w-]+)/(.+) news/articles.php?id=$1&artName=$2 [QSA,L,NC]

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

这是指向那篇文章的href链接:

<a href="https://www.example.com/news/articles/21/Hello-World">Article</a>

每当我尝试访问该页面时,都会出现“错误404-未找到”页面。我对编辑.htaccess文件不熟悉,请告诉我我的代码有什么问题,这样我就可以在链接中看到成功的重写,谢谢。

1
如果你需要使用的话,应该是这样的:RewriteRule ^news/articles/([\w-]+)/(.+) news/articles.php?id=$1&artName=$2 [QSA,L,NC] - anubhava
好的,我将你的重写规则复制粘贴到我的代码中,但仍然出现相同的错误。 - Magical Tomato
2个回答

1

您可以在 .htaccess 文件的顶部尝试以下内容来禁用 mod_spelling 选项:

<IfModule mod_speling.c>
   CheckSpelling off
   CheckCaseOnly off
</IfModule>

Options -MultiViews
RewriteEngine On

RewriteCond %{HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

RewriteRule ^(news/articles)/([\w-]+)/(.+) $1.php?id=$2&artName=$3 [QSA,L,NC]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

这将禁用多选选项。

摘要
有时,对文档的请求由于拼写错误或大小写错误而无法由核心Apache服务器提供。该模块通过尝试查找匹配的文档来解决这个问题,即使所有其他模块都放弃了。它通过比较请求目录中的每个文档名称与请求的文档名称而不考虑大小写,并允许最多一个拼写错误(字符插入/省略/转位或错误字符)来完成其工作。使用此策略匹配的所有文档名称都构建了一个列表。


还可以使用以下规则进行测试:RewriteRule ^(news/articles)/([\w-]+)/(.+) /$1.php?id=$2&artName=$3 [QSA,L,NC,R] - anubhava
当我请求 /news/articles 而不是 /news/articles.php 时,我会收到多个选择错误。 - Magical Tomato
抱歉,它没有起作用。当我只使用那个重写规则时,它会将我的链接切换回 /news/articles.php?id=21&artName=Hello-World。 - Magical Tomato
是的,我试过了,但我不认为错误是因为大小写问题而发生的。我认为多重选择错误出现是因为链接是/news/foobar/9/Hello-World,而浏览器希望我使用/news/foobar.PHP/9/Hello-World。它没有意识到Rewrite条件正在将foobar.php更改为foobar。 - Magical Tomato
1
你的选项-MultiViews救了我的命,原来我的托管服务要求我在文件中有RewriteBase /才能正常工作。在我这样做之后,我使用了Options -MultiViews,它对我起作用了。谢谢你的一切,你救了我的命。 - Magical Tomato
显示剩余2条评论

1
假设您已经按照评论中所述,在指令上添加了news/前缀,那么您还需要删除以下规则块:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
这是不正确的,会导致以下重写被跳过:/news/articles.php。这与后面的指令做的事情相同(而且后面的指令更好)。

1
所有在.htaccess中的更改应该是即时生效的,除非您看到了缓存响应...请确保清除浏览器缓存。是的,在这里你需要 Options -MultiViews,因为你的URL /news/articles 匹配了一个同名的文件,即 articles.php。如果启用了 MultiViews,则会在不使用 URL 参数的情况下提供 articles.php。(尽管默认情况下应该禁用 MultiViews。) - MrWhite
你的404响应是由Apache还是你的脚本生成的? - MrWhite
当我请求example.com/news/articles时,它会返回一个多项选择错误,内容如下:“您请求的文档名称(/news/articles)在此服务器上找不到。但是,我们找到了与您请求的名称类似的文档。”然后告诉我可用的文档为:/news/articles.php(常见基本名称)。 - Magical Tomato
当我写 /news/articles/9/Hello-World 仍然得到相同的错误页面 - 我以为你说这会生成404?... "错误404-未找到"。 - MrWhite
好的,这是预期的。这意味着你的.htaccess文件至少正在被处理。 - MrWhite
显示剩余18条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接