0%

wordpress | 多站点模式下访问某一文件夹文件返回 404

这是 wordpress 的一个多站点问题。

介绍一下背景,假设域名为 xxx.com,现在新建了一个新的站点 xxx.com/lumi,现在这个站点的主题需要上传一个 SDK,假设这个 SDK 的文件夹名称为 Extend

但是,在多站点子目录的配置下,访问 xxx.com/lumi/Extend/a.js 返回 404

我的 wordpress 是放置在 /var/www/wordpress 里面的。

所以,我将 Extend 上传到 /var/www/wordpress/Extend 或者 /var/www/wordpress/lumi/Extend 还是 404

然后我修改 nginx 配置,添加

1
2
3
location /lumi/Extend {
alias /var/www/wordpress/Extend;
}

也不行,经过我长期的排查,最后发现是 nginx 多站点配置问题。

nginx 多站配置为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# Upstream to abstract backend connection(s) for php
upstream php {
server unix:/tmp/php-cgi.socket;
# server 127.0.0.1:9000;
}

server {
listen 80;
## Your website name goes here.
server_name _;
## Your only path reference.
root /var/www/wordpress; # wordpress 的放置路径
## This should be in your http block and if it is, it's not needed here.
index index.php;

location = /favicon.ico {
log_not_found off;
access_log off;
}

location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}

location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass php;
#The following parameter can be also included in fastcgi_params file
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}

#ignored: “-” thing used or unknown variable in regex/rew
rewrite ^/([_0-9a-zA-Z-]+/)?wp-admin$ /$1wp-admin/ permanent;

if (-f $request_filename){
set $rule_2 1;
}
if (-d $request_filename){
set $rule_2 1;
}
if ($rule_2 = "1"){
#ignored: “-” thing used or unknown variable in regex/rew
}
rewrite ^/([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) /$2 last;
rewrite ^/([_0-9a-zA-Z-]+/)?(.*.php)$ /$2 last;
rewrite /. /index.php last;
}

最后发现,是最后一句话

1
rewrite /. /index.php last;

影响了。这句话是说,把所有的 url 都定向到 index.php

所以,我们要对这句话进行改造,还要加入

1
2
3
location /lumi/Extend {
alias /var/www/wordpress/Extend;
}

最终为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# Upstream to abstract backend connection(s) for php
upstream php {
server unix:/run/php/php7.4-fpm.sock;
#server 127.0.0.1:9000;
}


server {
listen 80;
## Your website name goes here.
server_name thlm.com www.thlm.com;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;#新增这两个
ssl_certificate /home/ubuntu/https/fullchain.crt;
ssl_certificate_key /home/ubuntu/https/private.pem;
#rewrite ^(.*) https://$server_name$1 permanent;
#return 301 https://$host$request_uri;

## Your only path reference.
root /var/www/wordpress; # wordpress 的放置路径
## This should be in your http block and if it is, it's not needed here.
index index.php;

location = /favicon.ico {
log_not_found off;
access_log off;
}

location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}

location /lumi/Extend {
alias /var/www/wordpress/Extend/;
}

location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass php;
#The following parameter can be also included in fastcgi_params file
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found on;
}
#ignored: “-” thing used or unknown variable in regex/rew
rewrite ^/([_0-9a-zA-Z-]+/)?wp-admin$ /$1wp-admin/ permanent;

if (-f $request_filename){
set $rule_2 1;
}
if (-d $request_filename){
set $rule_2 1;
}
if ($rule_2 = "1"){
#ignored: “-” thing used or unknown variable in regex/rew
}
rewrite ^/([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) /$2 last;
rewrite ^/([_0-9a-zA-Z-]+/)?(.*.php)$ /$2 last;
rewrite ^/(?!lumi/Extend)(.*)$ /index.php?$1 last;
}

完美解决。

ps: 2024-3-31

这里说一下为什么会出现这个问题。

wordpress 寻文件逻辑,会自动寻找你 url 路径下的文件,比如,你的 wordpress 是放在 /var/www/wordpress/ 中。

而,多站点子目录中的一个 urlxxx.com/lumi/Extend/xxx.js,它的寻址路径是 /var/www/wordpress/lumi/Extend/xxx.js

但是,即便是你把 /var/www/wordpress/ 文件夹中存上 /lumi/Extend/xxx.js 也不对。

是因为,默认配置中

1
rewrite /. /index.php last;

这一句话,让你把所有的文件,都通过 wordpressindex.php 来执行。如果,你文件本身是 wordpress 生成的,自然能借助 index.php 来查找路径。但是,咱们的文件,是独立的,所以,不能借助 index.php

所以,就需要上面的配置方式

  • /lumi 开头的进行资源重定向
  • 这些文件不能走 wordpressphp 解释器
请我喝杯咖啡吧~