好不容易让MediaWiki享受上了OSS,在进行CROS设置的时候想起我的主站中有些页面是需要访问心百科(MediaWiki的站点),添加完来源后,点开主站页面,结果就悲剧了,弹窗无法显示内容。
2025-03-06 20 20 09.png
按理说OSS的跨域设置最多影响图片引用,文字部分应该不至于。

先排查插件WP Wiki Tooltip(关于该插件的更多详细内容可以参考本站文章《在WordPress中插入MediaWiki的页面内容》),确实很久没有更新了。但上个月还是好用的,难不成因为WordPress升级后不兼容了?

进入插件的设置页面,点击测试按钮,提示“对不起,此URL的测试失败了!”。但在浏览器中输入API地址却能正常打开。试了一下维基百科的API,同样没用(被墙了,当然测试失败,只是我当时没有意识到)。

完了,估计是插件不能用了。

转念一想,不管怎么说,点击测试总归在心百科的服务器上会留下浏览记录吧。打开日志,果不其然,插件确实访问了API,但是被拦截了。原因说来可笑,之前为了反爬虫,禁用了所有的HTTP1.1的访问(详细经历见《快被爬虫搞破产了——网站反爬虫小记》一文)。

中间的排查不多赘述,简单介绍一下实际情况,插件中使用了WordPress的wp_remote_get函数来获取心百科中的内容,而这个函数只支持HTTP1.0和HTTP1.1两种方式。

把问题扔给DeepSeek,结果它给了一堆解决方案没一个能用的,有让我wp_remote_get函数强制设置成HTTP2.0,有让我放弃禁止HTTP1.1访问的,还有让我改核心代码的,甚至还有一堆代理和反代理的方案。最接近我需求的就是修改nginx配置,但它给的代码如下:

# 允许来自mindseed.cn的HTTP/1.1请求
if ($http_referer ~* (https?://(www\.)?mindseed\.cn)) {
    set $allow_http1 1;
}

# 其他请求必须使用HTTP/2.0
if ($server_protocol !~* "HTTP/2.0") {
    if ($allow_http1 != 1) {
        return 403;
    }
}

问题是,nginx并不支持if的嵌套,也不支持使用&&。到这时,DeepSeek就开始一本正经地绕圈子了,反正就是它不认为上面这种写法是嵌套。

也就是说,解决嵌套问题应该就可以实现我的要求了。根据网上搜索的结果,调整后的代码思路如下:

# 允许来自mindseed.cn的HTTP/1.1请求
set $allow_host 0;
if ($http_referer ~* (https?://(www\.)?mindseed\.cn)) {
     set $allow_host 1;
}

# 其他请求必须使用HTTP/2.0
set $allow_http 0;
if ($server_protocol = "HTTP/2.0") {
     set $allow_http 1;
}

set $disable_sign "${allow_host}${allow_http}";
if ($disable_sign = 00) {
    return 403;
}

$allow_host部分也可以通过检测IP地址的方式,总之就是要证明这是你允许放行的客户端。

重新加载nginx,再次进行API测试,终于通过了。

参考资料:nginx 如何实现if嵌套

最后修改:2025 年 03 月 09 日
如果觉得我的文章对你有用,请随意赞赏