在 .htaccess 中用 + 替换 URL 编码 (%20)

Replacing URL encoding (%20) with + in .htaccess

这是我到目前为止所得到的,它可以很好地重定向单个关键字,但如果 URL 包含 URL 编码的 space (%20),则效果不佳。

RewriteCond %{QUERY_STRING} (?:^|&)search=([^&]+) [NC]
RewriteRule ^jobs/?$ /?s=%1 [L,NC,R=301]

我想做的是将 %20 更改为 +.

例如,假设我有以下 URL:

http://www.example.com/jobs/?search=first%20second

我想将其重定向到以下内容:

http://www.example.com/?s=first+second

谢谢

...but not so well if the URL contains a URL encoded space (%20).

RewriteCond %{QUERY_STRING} (?:^|&)search=([^&]+) [NC]
RewriteRule ^jobs/?$ /?s=%1 [L,NC,R=301]

由于 QUERY_STRING 已经被 URL 编码,您需要在 RewriteRule 指令中包含 NE (noescape) 标志以防止任何URL 编码字符串被双重编码。这不仅适用于 spaces(即 %20%2520),还适用于许多其他 non-alphanumeric 字符嗯。

例如:

RewriteRule ^jobs/?$ /?s=%1 [NE,L,NC,R=301]

还需要用+替换%20吗?在查询字符串中 spaces 是否被 URL 编码为 %20+ 对接收应用程序来说并不严格。两者都将 URL-decoded 作为文字 space.

注意:只有在查询字符串中 space 才能被 URL 编码为 +。在 URL 的其他部分,+ 被视为文字字符(加号)。

searchURL参数值中用+替换%20

如果你想用 search URL参数值那么你可以这样做:

假设:

  • 只对“搜索”URL 参数感兴趣,因为您目前正在丢弃所有其他 URL 参数。
  • 可以有任意数量的 %-encoded spaces,即。 %20,在URL参数值中。

例如:

# Replace all "%20" in the "search" URL parameter with "+"
# eg. "/jobs?search=foo%20bar%20baz%20pop" to "/jobs?search=foo+bar+baz+pop"
RewriteCond %{QUERY_STRING} (?:^|&)(search)=([^&]*)%20([^&]*) [NC]
RewriteRule ^jobs/?$ [=12=]?%1=%2+%3 [N]

# Redirect "/jobs/?search=<foo>" to "/?s=<foo>"
# (Unchanged from original redirect)
RewriteCond %{QUERY_STRING} (?:^|&)search=([^&]+) [NC]
RewriteRule ^jobs/?$ /?s=%1 [NC,NE,R=302,L]

第一条规则在 内部 重复循环,直到所有出现的 %20 都已替换为 URL 参数值中的 +N (next) 标志使规则集从顶部重新开始。在 Apache 2.4+ 上,您可以设置迭代次数的上限(安全),例如。 N=20。如果没有 %20 则基本上会跳过此规则(因为条件在初始调用时不匹配)。

替换 字符串中的[=38=] (dollar-zero) 反向引用捕获整个URL-path(保存重复)。 %1 (percent-one) 反向引用仅包含“搜索”URL 参数名称(同样,保存重复)——最后匹配的 CondPattern[= 中的第一个捕获组88=].

%2%3 反向引用保存最后匹配的 CondPattern 中第二和第三捕获组的值,即。值 beforeafter URL 参数值中的最后一个 %20 字符序列。

此规则需要靠近 .htaccess 文件的顶部。

第二条规则与您原来的重定向指令相同,实际执行重定向,将 URL-path 和 search URL 参数更改为 s

您需要在测试前清除浏览器缓存,因为之前的 301(永久)重定向已被您的浏览器缓存。使用 302(临时)重定向进行测试 - 以避免缓存问题 - 只有在一切正常时才更改为 301。