Wordpress更新提示Too Many Requests解决方案
发现问题
先解释一下Too Many Requests
在HTTP协议中,响应状态码 429 Too Many Requests 表示在一定的时间内用户发送了太多的请求,即超出了“频次限制”。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/429
意思就是访问太频繁导致的, 但很多用户可能没有进行访问. 这可能与Wordpress验证机制有关吧, 猜测其他网站是按IP判断, wp官网可能用的IP段, 或是其他吧.
这就导致你可能没有访问过Wordpress的官网, 还是会出现这个423的错误, 安装插件或是更新等操作都会报错.
做出假设
既然服务器无法访问, 那么试试本地是否可以. 如果可以的话, 在本地下载好所需压缩包, 上传到服务器使其使用本地文件更新.
正常点击更新, 会有报错信息. 但是会有url信息, "正在从: https://downloads.wordpress.org/release/zh_CN/wordpress-x.x.zip下载", x.x就是更新的版本, 可以将连接复制一下直接下载下来.
提出方案
- hook函数site_transient_update_core
- 修改class-wp-upgrader.php文件
第一种是hook函数"site_transient_update_core", 使其在更新的时候返回一个其他连接进行下载更新. 目前网络中很多博主会提供这个方法, 并且放上自己的CDN连接, 切记不要轻易使用他人提供的连接进行更新.
第二种是直接改更新文件, 因为毕竟更新不是每天都需要的, 一两个月能用上一次, 所以改一次也不会浪费多少时间. 所以个人推荐这种, 毕竟所有操作透明都是自己操作.
实际实施
第一种很简单, 只需要在你的主题 functions.php(部分主题提供自定义代码文件所以并不是必须) 中添加以下代码.
add_filter('site_transient_update_core', function ($value) {
foreach ($value->updates as &$update) {
if ($update->locale == 'zh_CN') {
$update->download = '#实际下载地址#';
$update->packages->full = '#实际下载地址#';
}
}
return $value;
}
简单解释一下, 判断如果语言是中文, 则将下载地址以及和包完整地址替换. 实际连接需要自己去搞定, 举例: 刚才不是下载完整包了么, 可以把这个包直接上传到你的网站根目录, 假设你的域名是 aabb.com, 更新的版本是5.5.1, 那么这个连接填写的就是"https://aabb.com/wordpress-5.5.1-zh_CN.zip", 后面的文件名不必纠结, 改什么都无所谓.
但是更新过后记得要把这段代码注释掉. 否则下次更新会一直循环, 检测到5.5.2个更新, 然后hook一直再给5.5.1的包.
第二种也不难, 还是刚才下载的完整包, 上传到服务器中, 位置随意. 找到wordpress安装目录"wp-admin/includes/class-wp-upgrader.php"。
/**
* Download a package.
*
* @since 2.8.0
* @since 5.5.0 Added the `$hook_extra` parameter.
*
* @param string $package The URI of the package. If this is the full path to an
* existing local file, it will be returned untouched.
* @param bool $check_signatures Whether to validate file signatures. Default false.
* @param array $hook_extra Extra arguments to pass to the filter hooks. Default empty array.
* @return string|WP_Error The full path to the downloaded package file, or a WP_Error object.
*/
public function download_package( $package, $check_signatures = false, $hook_extra = array() ) {
/**
* Filters whether to return the package.
*
* @since 3.7.0
* @since 5.5.0 Added the `$hook_extra` parameter.
*
* @param bool $reply Whether to bail without returning the package.
* Default false.
* @param string $package The package file name.
* @param WP_Upgrader $this The WP_Upgrader instance.
* @param array $hook_extra Extra arguments passed to hooked filters.
*/
$reply = apply_filters( 'upgrader_pre_download', false, $package, $this, $hook_extra );
if ( false !== $reply ) {
return $reply;
}
if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) { // Local file or remote?
return $package; // Must be a local file.
}
if ( empty( $package ) ) {
return new WP_Error( 'no_package', $this->strings['no_package'] );
}
$this->skin->feedback( 'downloading_package', $package );
$download_file = download_url( $package, 300, $check_signatures );
if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) {
return new WP_Error( 'download_failed', $this->strings['download_failed'], $download_file->get_error_message() );
}
return $download_file;
}
找到这个 "download_package" 的函数. 在函数内的第一行添加以下内容.
$package = "/tmp/wordpress-5.5.zip";
后面路径就是你上传的路径, 你也可以在这里添加上第一步制作的连接. 然后再回到后台点击更新就可以了, 这种方法的好处就是, 你修改过的这个文件会在更新的时候覆盖掉, 防止出现hook更新之后忘了注释导致的一些问题.
方法二适用于更新主题和插件, 但是只有更新Wordpress会恢复文件, 如果更新插件或者主题, 改过记得改回去.
扩展
其实或多说少都有些许不方便, 毕竟涉及到代码. 在本地测试的时候因为从Wordpress后台直接安装或更新插件, 下载都很慢而且还容易因为网络问题下载出错.
所以就在本地测试的时候给Wordpress一个Proxy, 这样走其他一些线路会快一点, 生产环境如果有靠谱的也可以这么使用.
找到根目录下 wp-config.php, 添加以下代码
define('WP_PROXY_HOST', '127.0.0.1');
define('WP_PROXY_PORT', '10001');
define('WP_PROXY_USERNAME', 'username');
define('WP_PROXY_PASSWORD', 'password');
define('WP_PROXY_BYPASS_HOSTS', 'localhost, *.xx.com');
- WP_PROXY_HOST: 代理主机的IP
- WP_PROXY_PORT: 代理主机的端口
- WP_PROXY_USERNAME: 代理认证所需要的用户名, 如果没有则留空
- WP_PROXY_PASSWORD: 代理认证所需要的密码, 如果没有则留空
- WP_PROXY_BYPASS_HOSTS: 排除名单, 名单内的网址网域不经过代理
出了代理, 其他办法都是千篇一律. 替换下载时候的连接而已, WP的大版本还是比较值的更新的, 毕竟会修复很多漏洞.
文章评论