重写url变量包含%2F以进行斜杠转义时的404状态标头

时间:2019-04-07 14:24:44

标签: php regex wordpress url-rewriting wpml

我创建了一个wordpress网站,该网站通过将2个查询vars传递给具有我的自定义php模板的WP页面来动态显示约40万种产品。我正在使用WPML来翻译我的页面,并且启用了保留url vars _brand和_sku的选项。使用此设置,所有功能都可以正常工作(页面显示和状态为200好的标题)。语言切换器还会保留我的查询变量。

URL看起来像: domain.com/en/products /?_ brand = JCB&_sku = 01%2F117903

但是,由于我希望该网址显示为domain.com/en/products/a-brand/a-sku,因此我已将以下重写规则添加到我孩子的function.php中。

function rewrite_products()
{
    //en
    add_rewrite_rule('^products/([^&]+)/([^&]+)', 'index.php?page_id=93837&_brand=$matches[1]&_sku=$matches[2]', 'top');
    //nl
    add_rewrite_rule('^producten/([^&]+)/([^&]+)', 'index.php?page_id=93871&_brand=$matches[1]&_sku=$matches[2]', 'top');
    //fr
    add_rewrite_rule('^produits/([^&]+)/([^&]+)', 'index.php?page_id=93875&_brand=$matches[1]&_sku=$matches[2]', 'top');
    //de
    add_rewrite_rule('^produkte/([^&]+)/([^&]+)', 'index.php?page_id=93876&_brand=$matches[1]&_sku=$matches[2]', 'top');
    //es
    add_rewrite_rule('^productos/([^&]+)/([^&]+)', 'index.php?page_id=93877&_brand=$matches[1]&_sku=$matches[2]', 'top');
}

add_action('init', 'rewrite_products');

function rewrite_product_tags()
{
    add_rewrite_tag('%_brand%', '([^&]+)');
    add_rewrite_tag('%_sku%', '([^&]+)');
}
add_action('init', 'rewrite_product_tags', 10, 0);

我现在可以浏览到所需的URL,并获得具有正确产品的同一页面,但是标头现在提供404作为状态。

WPML的语言切换器还会丢弃我的查询变量,而只是将/ products / a-brand / a-sku重定向到例如/ producten(/ products的翻译)。

但最重要的是,404标头状态不允许我索引我在站点地图中转储的页面(大约2M URL),因为Google认为该URL是404且未索引这些页面。相比之下,这是一个巨大的问题。

我将其归结为以下问题:

  • 我正在使用rawurlencode,它会更改sku中的/等字符 到%2F
  • 这将导致标题为404
  • JCB / 005549646Z /这个网址可以完美显示(显示良好的标题)
  • JCB / 01%2F117903 /显示正常,但具有404标头

在模板中设置标题无效。我的正则表达式错了吗?任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:0)

我猜该错误是与WordPress核心相关或我的父主题中的某个地方。无论如何,我从未找到解决方案,只有一种解决方法,在字符串编码时将%2F替换为!2F

//Custom encoding en decoding to stop %2F 404 headers
function url_decode($encoded)
{
    $encoded = str_replace('!2F', '%2F', $encoded);
    $part_url = urldecode($encoded);

    return $part_url;
}

function url_encode($part_url)
{
    $encoded = rawurlencode($part_url);
    $encoded = str_replace('%2F', '!2F', $encoded);
    return $encoded;
}