.htaccess RewriteRule 从 long url 显示 short url

.htaccess RewriteRule from long url to show short url

我正在尝试将 url 从长改写为短,但无法解决这个问题。

我的调查重写效果很好,但在完成我的调查后 php 重定向到 www.example.com/survey_thank_you.php?survey_id=1 但我想像 www.example.com/thank_you

一样显示 url

我什至不确定这是否可能。

我是 .htaccess 的新手,我几乎尝试了一切

.htaccess

Options +FollowSymLinks
Options -MultiViews
RewriteEngine on


RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

RewriteRule ^survey_thank_you.php?survey_name=([0-9a-zA-Z]+)/?$ Thank_you [L,NC,QSA]
RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name= [L,NC,QSA] #works like charm.

任何帮助或指示将不胜感激。

解决方案:

Options +FollowSymLinks
Options -MultiViews
RewriteEngine on


RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^survey_id=([0-9a-zA-Z]+)/?$
RewriteRule ^survey_thank_you\.php$ /%1/thank_you [R,L,QSD]
RewriteRule ^([0-9a-zA-Z]+)/thank_you$ survey_thank_you.php?survey_id= [L,NC,QSA]


RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name= [L,NC,QSA]

but after completing my survet php redirects to www.example.com/survey_thank_you.php?survey_id=1

您需要“更正”PHP 在调查后将您重定向到的 URL。如果所需的 URL 是 /thank_you(或 /Thank_you?),那么 PHP 应该重定向到那个 URL。

然后您在 .htaccess 中使用 mod_rewrite 在内部将 /thank_you 重写回您的应用程序可以理解的 URL。 IE。 /survey_thank_you.php?survey_id=1。但是,这里面还有一个问题,查询字符串中的1survey_id)是从哪里来的呢?大概你不想硬编码这个?所以这需要传入请求的URL。例如。 /1/thank_you 或者 /thank_you/1?

然而,这真的有必要吗?生成的“谢谢”页面不是应该被索引的页面,也不是用户通常导航到的页面,因此在这里实现 user-friendly URL 似乎不是一个值得的练习?

RewriteRule ^survey_thank_you.php?survey_name=([0-9a-zA-Z]+)/?$ Thank_you [L,NC,QSA]
RewriteRule ^([0-9a-zA-Z]+)/?$ survey_form.php?survey_name= [L,NC,QSA] #works like charm.

您在指令中使用了 survey_name URL 参数(引用字母数字值),但在指令中使用了 survey_id(“数字”?)URL 参数你之前的例子?那么,它是哪一个?还是这些规则无关?

您说第二条规则“很有魅力”,但是如何呢? URL 你要求什么?这似乎将 /Thank_you 重写为 survey_form.php?survey_name=Thank_you - 但这看起来不正确?

如评论中所述,RewriteRule 模式 仅与 URL-path 匹配。要匹配查询字符串,您需要一个额外的 condition 来匹配 QUERY_STRING 服务器变量。这也需要是外部 3xx 重定向,而不是内部重写(以更改用户看到的 URL)。这里存在另一个问题...如果您不更改 PHP 脚本重定向到的 URL 那么用户将在提交表单后遇到 两次 重定向.

您还需要注意避免重定向循环,因为您在内部以相反的方向重写请求。您需要防止在重写请求后触发重定向。 IE。仅重定向来自用户的直接请求。

因此,为了回答您的具体问题,应该改写如下:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^survey_name=[0-9a-zA-Z]+/?$
RewriteRule ^survey_thank_you\.php$ /Thank_you [QSD,R,L]

针对 REDIRECT_STATUS 环境变量的检查确保只处理直接请求,而不是稍后重写的内部重写请求。 REDIRECT_STATUS 在初始请求中为 ,并在第一次成功重写后设置为字符串 200(如 200 OK 状态)。

QSD 标志 (Apache 2.4) 是从重定向响应中丢弃原始查询字符串所必需的。

所以上面会重定向 /survey_thank_you.php?survey_name=<something>/Thank_you

但是这是失去了“survey_name”(或者survey_id?),所以为了保留“survey_name”也许应该更像下面这样:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^survey_name=([0-9a-zA-Z]+)/?$
RewriteRule ^survey_thank_you\.php$ /%1/Thank_you [QSD,R,L]

其中 %1 是对前面 CondPattern.[=40= 中捕获的 survey_name URL 参数值的反向引用]

但是,您随后需要修改您的重写,将其变回可理解的 URL。

(但如果不首先更改应用程序中的实际 URL,您可能一开始就不应该这样做。)