我有一个包含页面URI的重写规则:
(<page-uri>)/someaction/(\\d+)
如果页面的URI包含西里尔文字符,例如
доска-объявлений
, 规则存储为:
(%d0%b4%d0%be%d1%81%d0%ba%d0%b0-%d0%be%d0%b1%d1%8a%d1%8f%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9)/someaction/(\\d+)
如果您转到包含指向与规则匹配的URL的链接的页面并单击该链接,浏览器将加载目标页面而不会出现问题,WordPress能够将规则与请求的URL匹配。
但是,在Safari(Mac)中,如果使用右键单击>复制链接复制URL,然后尝试通过将复制的URL粘贴到新选项卡来加载目标页面,则会出现404 Not Found错误。
在Safari中复制URL时,URL以百分比编码存储,字符用于表示西里尔文字符的八位字节,所有字符均为大写:
%D0%B4%D0%BE%D1%81%D0%BA%D0%B0-%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9/someaction/1
我无法在Chrome或Firefox(都是Mac)中重现这个问题,因为它们都使用小写字符来表示八位字节来存储URL。
带有百分比编码的URL是WordPress通过$_SERVER[\'REQUEST_URI\']
变量问题是,负责将请求的URI与重写规则匹配的代码会进行区分大小写的比较(请参阅parse_request
中的方法/wp-includes/class-wp.php
), 让WordPress无法接受我的规则
%D0%B4%D0%BE%D1%81%D0%BA%D0%B0-%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9
以及
%d0%b4%d0%be%d1%81%d0%ba%d0%b0-%d0%be%d0%b1%d1%8a%d1%8f%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9
表示相同的字符序列。
当浏览器使用不同大小写的八位字节发送请求时,有人知道如何防止404未找到错误吗这是WordPress应该支持的吗?还是应该尝试从重写规则中删除页面URI以避免出现问题
SO网友:Willington Vega
我最终遵循了@KolyaKorobochkin的建议,添加了包含转义八位字节的重写规则的大小写版本。
$regular_page_uri = get_page_uri( $page->ID );
$uppercase_page_uri = preg_replace_callback(
\'/%[0-9a-zA-Z]{2}/\',
create_function( \'$x\', \'return strtoupper( $x[0] );\' ),
$regular_page_uri
);
The
Percent Encode Capital Letter 插件使用类似的方法将每个URL中的八位字节转换为大写版本。然而,插件已经过时,可能无法在所有必要的地方进行转换。此外,我相信我正在开发的插件的大多数用户不会有带有编码八位字节的URL,所以运行
preg_replace_callback
对于所有URL来说,都是不必要的工作。
建议使用大写字符表示八位字节进行百分比编码(请参阅RFC3986, 第2.1节)。因此,更好的解决方案是让WordPress更新utf8_uri_encode
函数使用它们来转义八位字节。我测试的大多数浏览器似乎都保持原来的大小写,而其他浏览器,如Safari,如果有机会的话,会将其转换为大写。