404 状态 header 当重写 url 变量包含用于斜杠转义的 %2F
404 status header when rewrite url variable contains %2F for slash escape
我创建了一个 wordpress 网站,它通过将 2 个查询变量传递到具有我的自定义 php 模板的 WP 页面来动态显示大约 40 万种产品中的一种。我正在使用 WPML 翻译我的页面,并且启用了保留 url vars _brand 和 _sku 的选项。使用此设置一切正常(页面显示和状态 200 ok header)。语言切换器还保留我的查询变量。
URL 看起来像:
域名.com/en/products/?_brand=JCB&_sku=01%2F117903
但是因为我希望 url 像域一样显示。com/en/products/a-brand/a-sku 我已经将以下重写规则添加到我的 child的functions.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 并且我得到了包含正确产品的相同页面,但是 header 现在显示 404 作为状态。
WPML 的语言切换器也丢弃了我的查询变量,只是将 /products/a-brand/a-sku 重定向到,例如 /producten(/products 的翻译)。
但最重要的是,404 header 状态不允许我索引我在站点地图中转储的页面(大约 2M url,因为 google 认为url's 是 404's 并且不索引那些。这在对比中是一个巨大的问题。
我将其归结为以下问题:
- 我正在使用 rawurlencode 来更改 sku 中的 / 等字符
到 %2F
- 这导致 header 成为 404
- JCB/005549646Z/ 这个 url 完美(显示效果很好 header)
- JCB/01%2F117903/ 显示正常但有 404 header
在模板中设置 header 无效。我的正则表达式错了吗?感谢您的帮助!
我猜这个错误与核心 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;
}
我创建了一个 wordpress 网站,它通过将 2 个查询变量传递到具有我的自定义 php 模板的 WP 页面来动态显示大约 40 万种产品中的一种。我正在使用 WPML 翻译我的页面,并且启用了保留 url vars _brand 和 _sku 的选项。使用此设置一切正常(页面显示和状态 200 ok header)。语言切换器还保留我的查询变量。
URL 看起来像: 域名.com/en/products/?_brand=JCB&_sku=01%2F117903
但是因为我希望 url 像域一样显示。com/en/products/a-brand/a-sku 我已经将以下重写规则添加到我的 child的functions.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 并且我得到了包含正确产品的相同页面,但是 header 现在显示 404 作为状态。
WPML 的语言切换器也丢弃了我的查询变量,只是将 /products/a-brand/a-sku 重定向到,例如 /producten(/products 的翻译)。
但最重要的是,404 header 状态不允许我索引我在站点地图中转储的页面(大约 2M url,因为 google 认为url's 是 404's 并且不索引那些。这在对比中是一个巨大的问题。
我将其归结为以下问题:
- 我正在使用 rawurlencode 来更改 sku 中的 / 等字符 到 %2F
- 这导致 header 成为 404
- JCB/005549646Z/ 这个 url 完美(显示效果很好 header)
- JCB/01%2F117903/ 显示正常但有 404 header
在模板中设置 header 无效。我的正则表达式错了吗?感谢您的帮助!
我猜这个错误与核心 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;
}