WordPress 相对路径配置(HTTPS、反向代理)
最近将以前用WordPress建的网站进行迁移,发现其中很多链接因为绝对路径的原因都失效了,所以就想了些办法,将其中的链接改为相对路径,并且顺手解决了过程中遇到的一些问题。
问题原因
问题的原因其实很简单,就是因为WordPress里使用的都是绝对路径,这些路径都是保存在数据库的,如果IP或者域名发生了变化,就会造成原来链接的失效。着急的读者可以直接看完整解决方案。
解决办法
查了网上的资料,发现我遇到的情况还是比较复杂的:
- 服务器的IP地址发生了变化;
- 服务器增加了HTTPS访问;
- 服务器的内外地址都不是默认端口(80、443)。
所以各种解决方案也都试了一下,最后算是比较圆满的解决了,简单记录一下。
修改wp-config.php
在wp-config.php
的最后加上以下语句:
1 | $home = ‘http://’.$_SERVER['HTTP_HOST']; |
这种修改的方法,其实并不真正改为“相对路径”,而是通过判断域名,将域名付给home
和siteurl
两个全局变量,这样访问路径会随访问域名改变,很适合网站迁移时使用。
类似地,还有一种基本相同的修改方法:在wp-config.php
的require_once ABSPATH . 'wp-settings.php';
语句之前添加以下代码:
1 | $home = 'http://'.$_SERVER['HTTP_HOST'].'/'; |
我用了下面这一段代码,确实可以解决一部分内容的访问,主要是wp-content
目录下的内容可以正常访问。
安装WordPress插件
对相对路径的需求可以说不在少数,所以也就有热心的开发者开发了相应的插件,查了一下还是有挺多的,我使用的是Make Paths Relative
这一款,使用截图如下:
如果对PHP或者WordPress不是很了解的话,我推荐使用这个方法,当然如果考虑到安全性,还要看一下插件的说明,是否适合生产环境使用。
使用插件对settings的影响
最后,我也选择使用插件来修改相对路径,但是也发现了一个很有意思的错误:如果在settings保存时,WordPress Address(URL)
和Site Address(URL)
,也会根据插件中的Site Address
截取相对路径,如果两者相同,那么保存到数据库wp_options
表home
和siteurl
就会变成空字符串,就会导致数据库错误而无法启动。这个时候就必须要把wp_options
表home
和siteurl
的值改回来才可以。
出现这个问题的原因当然是由于插件造成的,在这个问题得到修复之前,为了避免这个问题,在修改General Settings的时候应该先停用Make Paths Relative。
配置HTTPS访问
我在内网部署WordPress服务,只提供HTTP服务,通过反向代理提供外网的HTTPS访问。
根据Word Press的官方说明,如果是以上情景,应当在wp-config.php
进行如下配置:
1 | define('FORCE_SSL_ADMIN', true); |
注意:以上这段代码同样要加在require_once(ABSPATH . 'wp-settings.php');
之前。
但是,实际上加了这一段代码以后,我反而不能通过HTTPS访问管理页面了,而是会直接重定向为以HTTPS协议访问内网服务地址。
之所以出现这样的问题,是因为上面修改相对路径造成的,更准确地说,是WP_HOME
被硬编码为内网地址,而内网地址只能以HTTP的方式提供服务,所以就不可能通过HTTPS访问了。因此,为了配置HTTPS访问,还是使用插件设置相对路径为好。
反向代理的HOST设置
在使用Nginx提供HTTPS反向代理的时候,如果WordPress内部有重定向或者跳转,就有可能跳转到内网的地址,跳转的地址其实是由$_SERVER['HOST']
决定的,所以可以采取的解决办法有两个:
- 在内网的HOST中添加DNS记录,以域名而不是IP地址访问服务;
- 反向代理转发的时候,通过
X-Forwarded-Host
向WordPress服务传递域名信息。
我采用的是第2种方法,需要注意的是,要在Nginx的配置文件和wp-config.php
文件中进行修改,具体的修改方法详见完整解决方案。
管理页面CSS与JS丢失
在配置好HTTPS访问之后,网站的内容正常,但是管理页面仍然可能出问题:wp-admin/
的load-scripts.php
和load-styles.php
的URL是HTTP协议,也就无法被加载。
这两个php的功能实际上WordPress为了减少对后台服务的请求,将页面所需要的CSS和JS文件分别合并成一个文件,这样就各自只需要一个请求。为了解决这个问题,也有两种解决办法:
-
在
wp-includes
文件夹里找到functions.php
,在最后加入下面代码,更换JS/CSS路径为相对路径:1
2
3
4
5
6
7
8
9add_filter('script_loader_src', 'agnostic_script_loader_src', 20,2);
function agnostic_script_loader_src($src, $handle) {
return preg_replace('/^(http|https):/', '', $src);
}
add_filter('style_loader_src', 'agnostic_style_loader_src', 20,2);
function agnostic_style_loader_src($src, $handle) {
return preg_replace('/^(http|https):/', '', $src);
} -
在网站根目录的wp-config.php文件中,添加以下这句代码即可:
1
define('CONCATENATE_SCRIPTS', false);
这段代码的作用是禁止把CSS/JS文件进行合并。
对于以上两种方法,推荐使用方法2,一来方法2更加简单,二来方法1修改的文件可能会由于WordPress更新而被覆盖。所以能通过修改wp-config.php实现的,尽量不要修改其他源码。
完整解决方案
最后,给出解决以上问题后的完整解决方案。假设我们的网站拓扑如下:
需要设置的包括Nginx反向代理配置文件、WordPress的wp-config.php
文件以及WordPress的后台管理设置,分别如下。
Nginx反向代理配置
文件内容如下:
1 |
|
wp-config.php
文件配置
1 |
|
WordPress后台配置
设置WordPress Address
和Site Address
为反向代理服务地址(HTTPS协议)。
Tips
-
简要写法举例:
1
echo '<script>console.log("'.$_SERVER['HTTP_HOST'].'");</script>';
结论
我不会世界上最好的语言——PHP,之前也没用过互联网上最流行的内容管理系统——WordPress,数据恢复、网站迁移、相对URL、HTTPS、反向代理、插件Bug……算是基本折腾好了。感觉收获不少,简单做个记录。
参考资料:
- https://www.its404.com/article/qq_39339179/120841435
- http://www.ddbq.net/2021/01/wordpress使用frp内网穿透后样式丢失问题解决/
- https://www.seoo.net/maint/613.html
- https://stackoverflow.com/questions/32588692/how-does-concatenate-scripts-work-on-wp-config/32589922
- https://zhuanlan.zhihu.com/p/376040113
- Issue with SSL when using nginx reverse proxy | WordPress.org
- Nginx反向代理中使用proxy_redirect重定向url - 散尽浮华 - 博客园 (cnblogs.com)
- https://help.dreamhost.com/hc/en-us/articles/214693268-WordPress-wp-config-php-overview
- https://core.trac.wordpress.org/ticket/17048
- https://code.tutsplus.com/tutorials/50-filters-of-wordpress-filters-41-50--cms-21299
- https://wordpress.org/support/article/administration-over-ssl/
- https://wordpress.stackexchange.com/questions/250240/setting-serverhttps-on-prevents-access-to-wp-admin
- https://segmentfault.com/a/1190000023353059