NGINX反向代理Apache时WordPress固定链接返回404求助
解决WordPress固定链接在NGINX反向代理下的404问题
你遇到的核心问题是:NGINX把WordPress的固定链接(比如/what-we-do/)当成静态文件/目录去查找,而没有转发到Apache处理,导致返回404。这是因为你的NGINX配置里的location结构和try_files逻辑没有正确处理伪静态请求。
问题根源分析
当前配置中,location /嵌套了静态文件和PHP的location规则,虽然写了try_files $uri $uri/ /index.php?$args =404,但这个规则里的/index.php?$args是让NGINX自己去查找这个文件,而非转发到Apache——但NGINX本身不处理PHP,且固定链接请求根本不会匹配到.php的location规则,所以直接返回了404。
修复后的NGINX配置
重构你的NGINX配置,把静态文件处理、伪静态转发、PHP请求代理分开,确保所有非静态资源的请求都能转发到Apache:
upstream example_apache { ip_hash; server 127.0.0.1:8086; } server { listen [::]:80; listen 80; listen [::]:443 http2 ssl; listen 443 http2 ssl; server_name example.com www.example.com; root /var/www/example.com/live_site; access_log /var/log/nginx/access-example.com.log main; error_log /var/log/nginx/error-example.com.log; index index.php; # SSL Cert Configuration ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH DHE-RSA-CHACHA20-POLY1305 EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4 !SEED !CAMELLIA"; ssl_session_cache shared:SSL:100m; ssl_session_timeout 180m; ssl_dhparam /var/www/certs/dh4096.pem; ssl_certificate /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.fullchain.secp384r1.cer; ssl_certificate_key /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.secp384r1.key; ssl_certificate /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.fullchain.rsa4096.cer; ssl_certificate_key /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.rsa4096.key; # HSTS Configuration add_header Strict-Transport-Security "max-age=300; includeSubdomains;"; # OCSP Configuration ssl_trusted_certificate /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.fullchain.secp384r1.cer; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.4.4 8.8.8.8 valid=300s; resolver_timeout 10s; # LetEncrypt webroot alias location /.well-known/acme-challenge/ { alias /var/www/le_root/.well-known/acme-challenge/; } # www to non-www + HTTP to HTTPS redirect set $https_redirect 0; if ($server_port = 80) { set $https_redirect 1; } if ($host ~ '^www\.') { set $https_redirect 1; } if ($https_redirect = 1) { return 301 https://example.com$request_uri; } # 处理静态文件,直接返回并设置缓存 location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|svg)$ { expires max; add_header Cache-Control public; } # 主入口:先找静态资源,找不到就转发到Apache location / { try_files $uri $uri/ @proxy_to_apache; } # 命名location:转发所有非静态请求到Apache location @proxy_to_apache { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass_header Set-Cookie; proxy_set_header SSL_PROTOCOL $ssl_protocol; proxy_set_header SSL_CLIENT_CERT $ssl_client_cert; proxy_set_header SSL_CLIENT_VERIFY $ssl_client_verify; proxy_set_header SSL_SERVER_S_DN $ssl_client_s_dn; proxy_pass http://example_apache; } # 直接转发PHP请求到Apache location ~ \.php$ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass_header Set-Cookie; proxy_set_header SSL_PROTOCOL $ssl_protocol; proxy_set_header SSL_CLIENT_CERT $ssl_client_cert; proxy_set_header SSL_CLIENT_VERIFY $ssl_client_verify; proxy_set_header SSL_SERVER_S_DN $ssl_client_s_dn; proxy_pass http://example_apache; } }
配置说明
- 静态文件处理:单独的location匹配常见静态资源后缀,NGINX直接返回这些文件,实现你要求的“NGINX处理静态文件”的需求,同时设置缓存提升性能。
- 主location逻辑:
try_files $uri $uri/ @proxy_to_apache表示:- 先查找请求对应的静态文件(
$uri) - 找不到就查找对应的目录(
$uri/) - 两者都找不到,就交给
@proxy_to_apache这个命名location转发到Apache处理
- 先查找请求对应的静态文件(
- 命名location转发:所有伪静态请求(比如固定链接)都会走到这里,转发到Apache后,Apache的
.htaccess规则会把这些请求重写到index.php,完成WordPress的固定链接解析。 - PHP请求代理:单独的
.phplocation确保所有直接的PHP请求都直接转发到Apache处理。
额外检查项
- 确保Apache已经启用
mod_rewrite模块(可以通过a2enmod rewrite命令启用) - 确认Apache的虚拟主机配置中,对应站点的
AllowOverride All已经设置,这样.htaccess的规则才能生效 - 确保NGINX的
root路径和Apache的DocumentRoot完全一致(都是/var/www/example.com/live_site) - 修改配置后,重启NGINX(
systemctl restart nginx)和Apache(systemctl restart apache2)服务
内容的提问来源于stack exchange,提问作者Joseph Michael
相关产品推荐
相关产品推荐

