Nginx

php 中的 nginx 404 處理程序忽略 HTTP 狀態

  • August 2, 2016

這是在 CentOS 7.2 中通過 PHP-FPM 使用 nginx 1.6.3 和 PHP 7.0.7。

我已經使用 LAMP 執行了許多站點,並且一直在嘗試切換到 LEMP,但不斷出現的一個問題是我的頁面處理程序在狀態中一直顯示 404 錯誤,即使我在 PHP 中設置了不同的狀態。就好像 nginx 完全忽略了從 PHP 發送的 404 錯誤頁面的標頭。

/etc/nginx/nginx.conf 看起來像:

user web web;
worker_processes auto;
error_log /var/web/Logs/WebServer/nginx-error.log;
pid /run/nginx.pid;

events {
   worker_connections 1024;
}

http {
   log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

   access_log /var/web/Logs/WebServer/nginx-access.log  main;

   fastcgi_buffers 8 1024k;

   sendfile            on;
   tcp_nopush          on;
   tcp_nodelay         on;
   keepalive_timeout   65;
   types_hash_max_size 2048;

   include             /etc/nginx/mime.types;
   default_type        application/octet-stream;

   include /etc/nginx/conf.d/*.conf;
}

每個域的配置如下所示:

server {
   listen       80;
   server_name  www.something.com;

   root /var/web/www.something.com/;
   index index.php index.html;

   error_page 404 /PageHandler;

   location / {
       try_files $uri $uri/ /PageHandler =404;
       location ~ \.php$ {
           try_files $uri =404;
           fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
           fastcgi_index index.php;
           include fastcgi.conf;
       }
       location /PageHandler {
           try_files /PageHandler.php =500;
           fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
           include fastcgi.conf;
           fastcgi_param REDIRECT_STATUS 404;
       }
   }
}

非常簡單的 PHP 腳本是(是的,我知道標題是多餘的,但它仍然什麼都不做):

<?php
 http_response_code(200);
 header("HTTP/1.1 200 OK");
 header("Status: 200", true, 200);
?>
Test <?= $_SERVER["REQUEST_URI"] ?>, code <?= $_SERVER["REDIRECT_STATUS"] ?>

我已經搜尋了幾個小時沒有結果來解決這個問題。我已經嘗試了至少一百種不同的 .conf 格式,但它們都不起作用。我上面的內容至少將 REDIRECT_STATUS 設置為 404,但是如果找到頁面,我發現無法返回 200 狀態程式碼。我不能讓 nginx 總是返回 200,因為它實際上可能是真正的 404,因為實際腳本會測試數據庫中的目前 URL。

如何讓 nginx 遵守 PHP 的 HTTP 狀態標頭?

對我來說,這些嵌套location塊看起來很麻煩,而且它們不是必需的。試試這個:

server {
   listen       80;
   server_name  www.something.com;

   root /var/web/www.something.com/;
   index index.php index.html;

   try_files $uri $uri/ /PageHandler.php =404;

   location ~ \.php$ {
       try_files $uri =404;
       fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
       fastcgi_index index.php;
       include fastcgi.conf;
   }
}

顯而易見的事情是刪除它:

   error_page 404 /PageHandler;

這完全是多餘的,因為任何不是作為靜態文件找到的路徑都會被你的第一個引導到那裡try_fileserror_page它僅用於提供靜態錯誤頁面是必要或有用的。

引用自:https://serverfault.com/questions/793277