Apache mod_rewrite 将锚点添加到查询字符串
Apache mod_rewrite adding anchor to query string
我正在尝试使用查询字符串向 URL 添加锚点。原来的URL是
https://example.com/foo?query=123
它应该重定向到
https://example.com/foo?query=123#anchor
这些是我在 .htaccess
文件中的规则:
RewriteCond %{REQUEST_URI} ^/foo$
RewriteCond %{QUERY_STRING} ^query=[a-zA-Z0-9\s]*$
RewriteRule (.*) /foo?%{QUERY_STRING}#anchor [NC,NE,R=302,L,END]
您知道如何避免重定向循环吗?
根据您展示的示例,请您尝试以下操作。
请确保在测试您的 URL 之前清除您的浏览器缓存。
RewriteEngine ON
RewriteCond %{THE_REQUEST} \s/([\w-]+\?query=\d+)\s [NC]
RewriteRule ^ %1#anchor [L,R,NE]
Do you have an idea how to avoid the redirecting loop?
如果不以某种方式更改 URL 路径或查询字符串,服务器端 (Apache / .htaccess
) 重定向是不可能的。
重定向请求中#anchor
(或片段标识符)没有传递给服务器,所以相同 URL 匹配您的规则并触发另一个重定向以附加 #anchor
,一次又一次,等等
当您请求 /foo?query=123
时,请求被 302 重定向到 /foo?query=123#anchor
(您发布的规则已经这样做了)。但是,浏览器仅在重定向请求中发送回 /foo?query=123
(无片段标识符),因此该过程重新开始。
防止“服务器端”重定向中的重定向循环的唯一方法是以某种方式更改 URL 的其他元素,然后您可以在规则中检测到这些元素。例如。重定向到 /bar?query=123#anchor
或 /foo?query=123&noredirect=1#anchor
等
但是,片段标识符 (#anchors
) 仅供客户端 script/HTML 使用,因此如果 URL 需要 #anchor
那么这应该是使用 JavaScript 添加。
旁白:关于您现有规则的几点说明:
RewriteCond %{REQUEST_URI} ^/foo$
RewriteCond %{QUERY_STRING} ^query=[a-zA-Z0-9\s]*$
RewriteRule (.*) /foo?%{QUERY_STRING}#anchor [NC,NE,R=302,L,END]
没有必要同时使用 L
和 END
标志。 L
标志停止当前轮次的处理,END
标志停止重写引擎的所有进一步处理。但是,当与 R
标志一起使用时,它们的行为完全相同 - 无论您使用 L
还是 END
标志,所有进一步的处理都会停止。
query=[a-zA-Z0-9\s]*$
- 你已经使用了 \s
(whitespace) shorthand 字符 class - 这是多余的它永远不会在这里匹配。 (您的查询字符串值实际上可以包含 space 吗?)QUERY_STRING
服务器变量是 % 编码的,因此永远不会有文字 space。请求的查询字符串中的任何 spaces 将被 URL 编码为 %20
或 +
.
RewriteRule
指令中的 NC
(nocase
标志)是多余的,因为无论如何你都在匹配“一切”(即 .*
).无论如何,我敢打赌这完全是多余的,因为您没有在前面需要的条件下使用 NC
标志 - 如果有的话。
(.*)
- 在发布的规则中不需要带括号的子模式(捕获组),因为反向引用没有在任何地方使用。
RewriteCond %{REQUEST_URI} ^/foo$
- 不需要此条件,因为 URL 路径可以在 RewriteRule
模式中更有效地执行 [= =78=].
我正在尝试使用查询字符串向 URL 添加锚点。原来的URL是
https://example.com/foo?query=123
它应该重定向到
https://example.com/foo?query=123#anchor
这些是我在 .htaccess
文件中的规则:
RewriteCond %{REQUEST_URI} ^/foo$
RewriteCond %{QUERY_STRING} ^query=[a-zA-Z0-9\s]*$
RewriteRule (.*) /foo?%{QUERY_STRING}#anchor [NC,NE,R=302,L,END]
您知道如何避免重定向循环吗?
根据您展示的示例,请您尝试以下操作。 请确保在测试您的 URL 之前清除您的浏览器缓存。
RewriteEngine ON
RewriteCond %{THE_REQUEST} \s/([\w-]+\?query=\d+)\s [NC]
RewriteRule ^ %1#anchor [L,R,NE]
Do you have an idea how to avoid the redirecting loop?
如果不以某种方式更改 URL 路径或查询字符串,服务器端 (Apache / .htaccess
) 重定向是不可能的。
重定向请求中#anchor
(或片段标识符)没有传递给服务器,所以相同 URL 匹配您的规则并触发另一个重定向以附加 #anchor
,一次又一次,等等
当您请求 /foo?query=123
时,请求被 302 重定向到 /foo?query=123#anchor
(您发布的规则已经这样做了)。但是,浏览器仅在重定向请求中发送回 /foo?query=123
(无片段标识符),因此该过程重新开始。
防止“服务器端”重定向中的重定向循环的唯一方法是以某种方式更改 URL 的其他元素,然后您可以在规则中检测到这些元素。例如。重定向到 /bar?query=123#anchor
或 /foo?query=123&noredirect=1#anchor
等
但是,片段标识符 (#anchors
) 仅供客户端 script/HTML 使用,因此如果 URL 需要 #anchor
那么这应该是使用 JavaScript 添加。
旁白:关于您现有规则的几点说明:
RewriteCond %{REQUEST_URI} ^/foo$ RewriteCond %{QUERY_STRING} ^query=[a-zA-Z0-9\s]*$ RewriteRule (.*) /foo?%{QUERY_STRING}#anchor [NC,NE,R=302,L,END]
没有必要同时使用
L
和END
标志。L
标志停止当前轮次的处理,END
标志停止重写引擎的所有进一步处理。但是,当与R
标志一起使用时,它们的行为完全相同 - 无论您使用L
还是END
标志,所有进一步的处理都会停止。query=[a-zA-Z0-9\s]*$
- 你已经使用了\s
(whitespace) shorthand 字符 class - 这是多余的它永远不会在这里匹配。 (您的查询字符串值实际上可以包含 space 吗?)QUERY_STRING
服务器变量是 % 编码的,因此永远不会有文字 space。请求的查询字符串中的任何 spaces 将被 URL 编码为%20
或+
.RewriteRule
指令中的NC
(nocase
标志)是多余的,因为无论如何你都在匹配“一切”(即.*
).无论如何,我敢打赌这完全是多余的,因为您没有在前面需要的条件下使用NC
标志 - 如果有的话。(.*)
- 在发布的规则中不需要带括号的子模式(捕获组),因为反向引用没有在任何地方使用。RewriteCond %{REQUEST_URI} ^/foo$
- 不需要此条件,因为 URL 路径可以在RewriteRule
模式中更有效地执行 [= =78=].