编辑查询字符串时的 .htaccess 重定向

A .htaccess redirect while editing the query string

我正在尝试重定向到一个新域,同时保留查询字符串,但采用修改后的方式。

比如我要重定向:

http://guides.freshstoreinstant.com/fresh-store-instant/how-to-find-your-amazon-affiliate-key-secret-key

https://guides.freshlabs.group/search?query=how+to+find+your+amazon+affiliate+key+secret+key

所以我想:

  1. 从原来的URL中取出最后的"folder"(how-to-find-your-amazon-affiliate-key-secret-key)

  2. -替换为+

  3. 将结果附加到 https://guides.freshlabs.group/search?query= 并使用 301

  4. 重定向

我尝试了一些东西并且对 .htaccess 了解了一点,但是这个让我难住了

更新

使用 .htaccess 和 PHP 的组合可能会更容易。我可以用.htaccess将所有URL重写为index.php,然后用PHP替换字符并重定向吗?

使用 apache 的重写模块是不可能的,因为它不支持此类搜索和替换操作。它只会重写。如果您真的不能接受未更改的字符串,您可能仍然可以在处理逻辑中拆分它,那么您有以下选择:

要么引入另一个重写层,基于一些接受未改变的字符串的脚本引擎,通过正常的字符串操作和输出重定向头来转换它

或者你可以用 apache 的替代模块做一些事情,但你需要安装和加载它,而且它的使用并不容易(做了那个,抱怨了很多......)

或者使用一个看起来很奇怪但有效的解决方法:

RewriteEngine on

RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)/?$ https://guides.freshlabs.group/search?query=++++++++ [R=301,QSA]
RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)/?$ https://guides.freshlabs.group/search?query=+++++++ [R=301,QSA]
RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)/?$ https://guides.freshlabs.group/search?query=++++++ [R=301,QSA]
RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)/?$ https://guides.freshlabs.group/search?query=+++++ [R=301,QSA]
RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)/?$ https://guides.freshlabs.group/search?query=++++ [R=301,QSA]
RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)-([^/-]*)-([^/-]*)-([^/-]*)/?$ https://guides.freshlabs.group/search?query=+++ [R=301,QSA]
RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)-([^/-]*)-([^/-]*)/?$ https://guides.freshlabs.group/search?query=++ [R=301,QSA]
RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)-([^/-]*)/?$ https://guides.freshlabs.group/search?query=+ [R=301,QSA]
RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteRule ^/?fresh-store-instant/([^/-]*)/?$ https://guides.freshlabs.group/search?query= [R=301,QSA]

此规则集在动态配置文件(“.htaccess”样式文件)中的 http 服务器主机配置 中同样有效。


更新:

我意识到您要转换的示例字符串包含超过 9 个标记,这或多或少是 apache http 服务器支持的反向引用的硬编码限制。如果您可以重新编译源代码,您可以更改它,在这种情况下,上述解决方案很好,并且可以扩展到您认为安全的多个令牌。

如果这不是一个选项(通常),您需要尝试这样的事情:

RewriteEngine on

RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteCond %{QUERY_STRING} (^|&)query=(.+)&|$
RewriteRule ^/?fresh-store-instant/?$ https://guides.freshlabs.group/search [R=301,QSA]

RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteCond %{QUERY_STRING} (^|&)query=(.+)(&|$)
RewriteRule ^/?fresh-store-instant/([^/-]*)[-]?(.*)/?$ /fresh-store-instant/?query=%2+ [N,QSD]

RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteCond %{QUERY_STRING} !(^|&)query=
RewriteRule ^/?fresh-store-instant/([^/-]*)/?$ https://guides.freshlabs.group/search?query= [R=301,QSD]

RewriteCond %{HTTP_HOST} ^guides\.freshstoreinstant\.com$
RewriteCond %{QUERY_STRING} !(^|&)query=
RewriteRule ^/?fresh-store-instant/([^/-]*)[-](.*)/?$ /fresh-store-instant/?query= [N,QSD]

注意:我没有测试这个,只是记下来了,所以那里可能有一些小故障。它应该工作。它实现了多重重写策略:它在单独的 go 中重写每个标记,"storing" 该标记在初步查询参数中。一个接一个地组装令牌,直到执行最终的外部重定向,因为请求中不再存在要转换的令牌。


一般性评论:您应该始终更喜欢将此类规则放在 http 服务器主机配置中,而不是使用动态配置文件 (".htaccess")。那些动态配置文件增加了复杂性,通常是意外行为的原因,难以调试并且它们确实减慢了 http 服务器的速度。它们仅在您无法访问真正的 http 服务器主机配置(阅读:非常便宜的服务提供商)或坚持编写自己的规则(这是一个明显的安全噩梦)的应用程序的情况下作为最后的选择提供。

您可以使用 .htaccess 中的 mod_rewrite 执行此操作。在 .htaccess 文件的顶部尝试以下操作:

RewriteEngine On

RewriteRule ^(fresh-store-instant)/([^/]*)-([^/]*)$ /+ [N]
RewriteRule ^fresh-store-instant/([^/]+)$ https://guides.freshlabs.group/search?query= [R=302,L]
  1. 第一条规则重复重写请求(内部),将第二个路径段中的所有 -(连字符)替换为 +N (next) 标志显式触发重写循环。这应该谨慎使用;与任何类似递归的行为一样,它需要在某个时候 fail。 (注意:URL 路径中的 + 只是文字 +。)

  2. 一旦所有连字符都被替换,第二条规则触发到另一个域的外部重定向,将第二个路径段(现在包含 +)复制到目标 URL。 (注意:URL 的查询字符串部分中的 + 被接收服务器视为编码的 space。)

请注意,这是一个临时 (302) 重定向。只有在确认它工作正常后才更改为 301(永久)- 以避免缓存问题。

测试前清除浏览器缓存。

...while keeping the query string but in a modified way

您的示例源 URL 到 "keep" 上没有查询字符串?请注意,上述重定向会覆盖源 URL 上可能存在的任何查询字符串。如果要 "append" 来自请求的查询字符串,请在第二个 RewriteRule 中包含 QSA


更新:

the first "folder" can vary (e.g. http://guides.freshstoreinstant.com/fresh-store-builder/...)

如果文件夹的子集有限,那么最好明确命名每个文件夹,以避免与您站点上的其他 URL 发生潜在冲突。例如:

RewriteRule ^(fresh-store-(?:instant|builder))/([^/]*)-([^/]*)$ /+ [N]
RewriteRule ^fresh-store-(?:instant|builder)/([^/]+)$ https://guides.freshlabs.group/search?query= [R=302,L]

如果您使初始目录完全可变(如下所示),那么我可以想象这与现有的 URLs 冲突:

RewriteRule ^([\w-]+)/([^/]*)-([^/]*)$ /+ [N]
RewriteRule ^([\w-]+)/([^/]+)$ https://guides.freshlabs.group/search?query= [R=302,L]