【问题标题】:Repairing A Botched .htaccess Redirect Attempt修复拙劣的 .htaccess 重定向尝试
【发布时间】:2012-11-29 02:38:19
【问题描述】:

我尝试了大约 10 个现有 SO 问题的答案,但无济于事。使用 Salman A 在Rewrite rule that removes query string from URL and redirect 中的回答,我创建了以下 .htaccess 文件:

Options +FollowSymLinks
RewriteBase /
RewriteEngine On
RewriteCond %{QUERY_STRING} !=""
RewriteRule ^(.*) /$1? [R,L]

...目标是获取这样的网址:

http://www.example.com/index.php?c=web

……让它看起来像这样:

http://www.example.com/web

按照 Salman A 的回答后,网址看起来像:

http://www.example.com/?c=web

然后我在尝试剥离“?c=”部分时搞砸了一些东西——不幸的是我不知道我搞砸了什么——然后我删除了 .htaccess 文件,因为我不想搞砸其他任何事情。现在,即使没有 .htaccess 文件,一些 url——特别是我在测试 Salman A 的答案时点击的三个 url——仍然看起来像:

http://www.example.com/?c=web 

...即使我删除了 .htaccess 文件。三个问题:1)为什么尽管删除了 .htaccess 文件,更改仍然存在; 2)这是我需要担心的事情吗?并且,3)如何修改 .htaccess 文件以使所有 url 看起来像:

http://www.example.com/web

更新:这就是我担心的http://getluky.net/2010/12/14/301-redirects-cannot-be-undon/。如果我搞砸了 301 重定向并且新访问者访问了该网站,他们会被这个垃圾所困扰吗?有没有办法取消缓存?

【问题讨论】:

    标签: apache .htaccess


    【解决方案1】:

    当你说“取一个这样的 url,让它看起来像这样”,你的意思是让它在服务器上看起来像这样,还是在浏览器看起来像这样(两个完全不同的东西)。请参阅the top part of this answer 以获得一些说明。

    您实现的答案使 服务器 看到没有查询字符串的请求。在 URI /index.php?c=web 通过 URL/文件映射管道后,mod_rewrite 生成:/index.php,删除查询字符串 ?c=web,最后 Web 服务器获取 /index.php 并为其提供服务(无查询字符串)。当然,虽然这一切都在发生,但浏览器对 mod_rewrite 魔法一无所知,仍然会显示与它被告知要显示的 URL 相同的 URL,http://www.example.com/index.php?c=web,因为它从未被告知,这就是 URL你还能看到。

    如果您想更改 浏览器 看到的 URL,则需要从外部将浏览器重定向到新的 URL。你可以使用这样的东西:

    RewriteEngine On
    RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /(index\.php)?\?c=([^&\ ]+)
    RewriteRule ^ /%3? [L,R]
    

    所以当你的浏览器请求http://www.example.com/index.php?c=web时,这条规则会匹配查询字符串,并将浏览器重定向到结果/web,从而改变URL地址栏中的URL浏览器。浏览器现在看到这个新 URL,向服务器发出一个全新的请求,以获取这个新 URL。您可能希望将其改回原来的样子,因为我猜您在/web 处确实没有目录或文件。所以你这样做:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php?c=$1 [L]
    

    这使得 服务器 在有人请求 /web 时看到 /index.php?c=web

    【讨论】:

    • 我一直在研究您提供的链接(以及 Apache 文档)。我想要一个外部重定向。我现在正在通过 MAMP 进行试验:localhost:8888/DR/index.php 新指令:选项 +FollowSymLinks -MultiViews RewriteEngine on RewriteBase /DR/ 添加你的行,没有任何变化。请求http://localhost:8888/DR/index.php?c=web 仍会加载http://localhost:8888/DR/index.php?c=web 并仍会在浏览器中显示http://localhost:8888/DR/index.php?c=web
    • 抱歉格式很糟糕,由于字符限制,我不得不严重截断我的回复并编辑重要信息。在此处包含更多信息的“正确”方式是什么?我应该将其全部添加到原始问题中吗?评论格式/字符规则不太利于深入细节。我试图真正理解这一点,而不是寻找快速剪切和粘贴的解决方案。再次感谢。
    • @CL75 您无法在 cmets 中进行格式化,您需要编辑原始问题以阐明您想要的内容。但是将我的行添加到您的 URL 中,您需要调整我的示例以适合您的需要。我的示例假设您在?c=something 前面没有nothing。如果你有东西,我的示例需要修改以在 %{THE_REQUEST} 匹配中包含 DR。
    • 它工作了(虽然它仍然为主页附加index.php,但我想我可以解决这个问题。谢谢,如果你不介意我还有几个问题。%{THE_REQUEST} ignore everything before /index.php? I'm trying to understand why it works the same given =example.com/index.php` 或localhost:8888/index.php。另外,我应该使用R=301 标志吗?如果我这样做,除非他们手动这样做,否则这真的永远不会在用户的浏览器中取消缓存。我我对创建这样的半永久性更改犹豫不决。
    • @CL75 %{THE_REQUEST} 是 HTTP 请求的第一行,它不包含协议或主机名信息。如果请求确实包含协议和主机名,这意味着它是对代理的请求,请参阅:w3.org/Protocols/rfc2616/rfc2616-sec5.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 2015-08-15
    相关资源
    最近更新 更多