我有一个托管在Azure应用服务(不是专用VM(上的WordPress网站,我需要人们通过如下所示的URL访问首页:http://www.example.com/?tracking.id=12345
但是,WordPress正在重写URL,将tracking.id
中的点替换为下划线:http://www.example.com/?tracking_id=12345
我怎样才能阻止WordPress这样做?
,这只发生在主页上,查询变量在其他任何地方都保持不变。 如果你看一下wp-includes/canonical.php
,你也许能够弄清楚发生了什么(这也是redirect_canonical
过滤器所在的位置(
function prevent_underscores( $redirect_url, $requested_url ) {
if( isset( $_GET['tracking_id'] ) ) {
return $requested_url;
}
return $redirect_url;
}
add_filter( 'redirect_canonical', 'prevent_underscores', 10, 2 );
您可以在WordPress网站的设置选项卡中检查是否已选择并设置permalinks_type
。您可以参考 https://codex.wordpress.org/Using_Permalinks 了解详细信息。
此外,您可以利用第 3 部分 Wordpress 插件,请参阅 https://wordpress.org/plugins/custom-permalinks/。
接近,绝对与redirect_canonical
走在正确的轨道上。
我自己进一步深入研究了这个问题,发现这是PHP本身和WordPress中的重定向逻辑之间的问题的组合。如果你直接查看 php 全局$_GET
,你会发现这就是查询字符串参数被"错误"解析的地方。例如:
// For a url like: /some/path/?tracking.id=123
var_dump($_GET);
// array(1) { ["tracking_id"]=> string(3) "123" }
如果你继续挖掘redirect_canonical
代码,你最终会发现罪魁祸首是一堆函数调用,以 php 的 parse_str
方法结束:
// https://developer.wordpress.org/reference/functions/_remove_qs_args_if_not_in_url/
_remove_qs_args_if_not_in_url()
// https://developer.wordpress.org/reference/functions/remove_query_arg/
remove_query_arg()
// https://developer.wordpress.org/reference/functions/add_query_arg/
add_query_arg()
// https://developer.wordpress.org/reference/functions/wp_parse_str/
wp_parse_str()
// https://www.php.net/manual/en/function.parse-str.php
parse_str()
直接测试parse_str
会得到与查看 _GET 美元相同的结果:
$arr = [];
parse_str('tracking.id=123', $arr);
var_dump( $arr );
// array(1) { ["tracking_id"]=> string(3) "123" }
所有这些都表明,有一种稍微好一点的方法来设置自己的过滤器,以便获得更强大的结果。例如,@vidja编写过滤器的方式会导致页面在您希望它们被正确重定向时无法正确重定向(结果,WordPress 显示 404 未找到页面(。假设您有一个包含大量/sample-page
的页面,并且您尝试通过类似以下内容的网址访问您的网站:/sampl?tracking.id=123
。WordPress希望将其重定向到/sample-page/?tracking_id=123
,但@vidja的代码将返回原始(坏(URL,因为tracking_id
设置为$_GET。因此,在我看来,处理此问题的更好方法是替换重定向URL中您关心的特定查询字符串参数,这样Wordpress就可以按照它认为合适的方式重定向页面,但您也可以正确维护tracking.id
。这是看起来像这样:
add_filter( 'redirect_canonical', function ( $redirect_url, $requested_url ) {
return preg_replace( '/tracking_id=/', 'tracking.id=', $redirect_url );
}, 10, 2 );
如果你有多个带有句点的查询字符串参数需要维护,你甚至可以做如下的事情:
add_filter( 'redirect_canonical', function ( $redirect_url, $requested_url ) {
$query_params = [
'tracking_id' => 'tracking.id',
'foo_bar' => 'foo.bar',
];
foreach ( $query_params as $search => $replace ) {
$redirect_url = preg_replace( '/'.$search.'=/', $replace.'=', $redirect_url );
}
return $redirect_url;
}, 10, 2 );