WordPress多站点媒体缩略图与特色图片无法显示问题求助
解决WordPress多站点子目录迁移后缩略图不显示问题
问题现象
- 将项目站点迁移至作品集站点的子目录,搭建为WordPress多站点,已正确更新数据库URL及图片路径适配
sites/数字的多站点文件夹结构,但媒体缩略图和特色图片仍无法显示 - 媒体文件夹中可见图片,图片URL正确且可直接访问,但线上服务器缩略图调用
wp-includes目录下的默认图片(示例URL:https://siteurl/ntwrktheme/wp-includes/images/media/default.png),本地开发环境则正常调用wp-content/uploads目录下的图片(示例URL:http://thentwrkthemenew.local/wp-content/uploads/2024/01/default.png) - 当前使用xCloud的Nginx主机,现有Nginx配置如下:
# XCLOUD CONFIG BEFORE include xcloud-conf/meshkin.me/before/*; # Fastcgi cache path fastcgi_cache_path /etc/nginx/cache/meshkin.me levels=1:2 keys_zone=meshkin.me:100m inactive=60m; # End of Fastcgi cache path # WordPress multisite subdirectory rules. map $uri $blogname{ ~^/(?<blogpath>[^/]+/)files/(.*) $blogpath ; } map $blogname $blogid{ default -999; #Ref: https://wordpress.org/extend/plugins/nginx-helper/ #include /var/www/wordpress/wp-content/plugins/nginx-helper/map.conf ; } server { # Ports to listen on listen 443 ssl; listen [::]:443 ssl; http2 on; # Server name to listen for server_name meshkin.me; # Path to document root root /var/www/meshkin.me; # Paths to certificate files. ssl_certificate /etc/letsencrypt/live/meshkin.me/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/meshkin.me/privkey.pem; server_tokens off; add_header X-Frame-Options ""; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; location / { try_files $uri $uri/ /index.php?$args; } # File to be used as index index index.php index.html; # XCLOUD CONFIG SERVER include xcloud-conf/meshkin.me/server/*; location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|ttc|rss|atom|jpg|jpeg|gif|png|ico|webp|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|css|js)$ { access_log off; log_not_found off; expires max; add_header Cache-Control "public"; } location ~* /\.(?!well-known/) { deny all; } location ~\.(ini|log|conf)$ { deny all; } # Deny access to any files with a .php extension in the uploads directory location ~* /(?:uploads|files)/.*\.php$ { deny all; } location = /xmlrpc.php { deny all; } # Overrides logs defined in nginx.conf, allows per site logs. access_log /var/log/nginx/meshkin.me-access.log; error_log /var/log/nginx/meshkin.me-error.log; # The key to use when saving cache files, which will run through the MD5 hashing algorithm. fastcgi_cache_key "$scheme$request_method$host$request_uri"; # If an error occurs when communicating with FastCGI server, return cached content. # Useful for serving cached content if the PHP process dies or timeouts. fastcgi_cache_use_stale error timeout updating invalid_header http_500; # Allow caching of requests which contain the following headers. fastcgi_ignore_headers Cache-Control Expires Set-Cookie; # Show the cache status in server responses. add_header Fastcgi-Cache $upstream_cache_status; # Don't skip by default set $skip_cache 0; # POST requests and urls with a query string should always go to PHP if ($request_method = POST) { set $skip_cache 1; } if ($query_string != "") { set $skip_cache 1; } # Don't cache URIs containing the following segments if ($request_uri ~* "/wp-admin/|/wp-json/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml|/cart/|/checkout/|/my-account/") { set $skip_cache 1; } # Don't use the cache for logged in users or recent commenters if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|edd_items_in_cart|woocommerce_items_in_cart") { set $skip_cache 1; } location ~ ^(/[^/]+/)?files/(.+) { try_files /wp-content/blogs.dir/$blogid/files/$2 /wp-includes/ms-files.php?file=$2 ; access_log off; log_not_found off; expires max; } #avoid php readfile() location ^~ /blogs.dir { internal; alias /var/www/meshkin.me/wp-content/blogs.dir ; access_log off; log_not_found off; expires max; } if (!-e $request_filename) { rewrite /wp-admin$ $scheme://$host$request_uri/ permanent; rewrite ^(/[^/]+)?(/wp-.*) $2 last; rewrite ^(/[^/]+)?(/.*\.php) $2 last; } location ~ \.php$ { try_files $uri = 404; fastcgi_buffer_size 128k; fastcgi_busy_buffers_size 256k; fastcgi_buffers 4 256k; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php/php8.1-fpm-u1_meshkin.sock; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache meshkin.me; fastcgi_cache_valid 60m; add_header X-Cache $upstream_cache_status; add_header X-Frame-Options ""; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # Rewrite robots.txt rewrite ^/robots.txt$ /index.php last; } # Redirect http to https server { listen 80; listen [::]:80; server_name meshkin.me; return 301 https://meshkin.me$request_uri; } # Redirect www to non-www ssl server { listen 80; listen [::]:80; server_name www.meshkin.me; return 301 https://meshkin.me$request_uri; } # Redirect www to non-www server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name www.meshkin.me; # Paths to certificate files. ssl_certificate /etc/letsencrypt/live/meshkin.me/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/meshkin.me/privkey.pem; return 301 https://meshkin.me$request_uri; } # XCLOUD CONFIG AFTER include xcloud-conf/meshkin.me/after/*;
问题根源
现有Nginx配置使用的是WordPress旧版多站点的blogs.dir文件结构规则,但当前采用的是WordPress 3.5+引入的wp-content/uploads/sites/[blog_id]新结构,导致请求无法正确映射到实际存储的文件路径,最终触发默认图片 fallback。
修复方案
修改Nginx配置中的多站点文件处理规则,替换旧的blogs.dir相关配置,适配新的uploads/sites结构:
1. 更新map规则
替换原有的map $uri $blogname和map $blogname $blogid为以下内容,正确匹配子站点的文件请求并映射到对应blog_id:
# WordPress multisite subdirectory rules for uploads/sites structure map $uri $blog_id { ~^/[^/]+/wp-content/uploads/sites/([0-9]+)/ $1; default 0; } map $uri $blog_uri { ~^/([^/]+)/wp-content/uploads/sites/[0-9]+/(.*) /wp-content/uploads/sites/$blog_id/$2; }
2. 替换文件请求处理的location块
删除原有的以下两个块:
location ~ ^(/[^/]+/)?files/(.+) { try_files /wp-content/blogs.dir/$blogid/files/$2 /wp-includes/ms-files.php?file=$2 ; access_log off; log_not_found off; expires max; } #avoid php readfile() location ^~ /blogs.dir { internal; alias /var/www/meshkin.me/wp-content/blogs.dir ; access_log off; log_not_found off; expires max; }
添加适配新结构的location规则:
# Handle multisite uploads location ~* ^/[^/]+/wp-content/uploads/sites/([0-9]+)/(.*)$ { try_files $blog_uri $uri /index.php?$args; access_log off; log_not_found off; expires max; add_header Cache-Control "public"; }
3. 验证并重启Nginx
修改完成后,执行以下命令验证配置语法是否正确:
nginx -t
如果验证通过,重启Nginx服务:
systemctl restart nginx
额外步骤(可选)
如果缩略图仍不显示,可尝试重新生成缩略图:
- 安装并启用
Regenerate Thumbnails插件 - 运行插件的批量缩略图生成功能,确保所有缩略图正确生成到对应站点的
uploads/sites/[blog_id]/目录下
内容的提问来源于stack exchange,提问作者COBNETCKNN
相关产品推荐
相关产品推荐

