页面显示正确,但 Nginx 日志显示“找不到文件”


Page shown properly, but Nginx logs shows "File not found"

我正在使用Nginx和Codeigniter以及php5-fpm。一切"似乎"都工作得很好,页面显示出来,一切看起来都很棒。Ofcource这不是我在这里问这个问题的原因,我实际上有一个问题。

面临的问题是页面抛出了 404 错误,即使页面正确呈现,我仍然会得到 404(在日志中)。

我得到 404 的原因是 Nginx 无法打开我请求的文件,因为 Nginx 尝试直接打开 PHP 文件,而不是引用controller/method不幸的是 Codeigniter 以这种方式工作。

例如:
请求http://website.com/<controller>/<function>/<other_params>会导致 Nginx 日志中的 404,这背后的原因是open()无法打开指定的目录,因为它不存在,而不是引用controller/method

一些重要的日志:
Nginx错误日志:

[error] 4172#0: *482 open() "/var/www/<domain>/public/site/section/main" failed
(2: No such file or directory), client: <client_ip>, server: <domain>, request: "GET   
/site/section/main HTTP/1.1", host: "<domain>"  

正如我之前所说,Nginx试图直接访问该文件,而不是让Codeigniter处理它。

我的sites-enabled/ci配置:

server
{
    server_name <domain> *.<domain>;
    access_log /var/www/<domain>/access.log;
    error_log /var/www/<domain>/error.log;
    root /var/www/<domain>/public;
    index index.php index.html index.htm;

   location ~* '.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
    access_log        off;
    log_not_found     off;
    expires           360d;
}
    # enforce www (exclude certain subdomains)
#   if ($host !~* ^(www|subdomain))
#   {
#       rewrite ^/(.*)$ $scheme://www.$host/$1 permanent;
#   }
    # enforce NO www
    if ($host ~* ^www'.(.*))
    {
        set $host_without_www $1;
        rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
    }
    # canonicalize codeigniter url end points
    # if your default controller is something other than "welcome" you should change the following
    if ($request_uri ~* ^(/site(/index)?|/index(.php)?)/?$)
    {
        rewrite ^(.*)$ / permanent;
    }
    # removes trailing "index" from all controllers
    if ($request_uri ~* index/?$)
    {
        rewrite ^/(.*)/index/?$ /$1 permanent;
    }
    # removes trailing slashes (prevents SEO duplicate content issues)
   # if (!-d $request_filename)
   # {
   #     rewrite ^/(.+)/$ /$1 permanent;
   # }
    # removes access to "system" folder, also allows a "System.php" controller
    if ($request_uri ~* ^/(system|application))
    {
        rewrite ^/(.*)$ /index.php?/$1 last;
        break;
    }
    # unless the request is for a valid file (image, js, css, etc.), send to bootstrap
    #if (!-e $request_filename)
    #{
     #   rewrite ^/(.*)$ /index.php?/$1 last;
     #   break;
    #}
    # catch all
    error_page 404 /index.php;
    # use fastcgi for all php files
      location ~ '.php($|/)
    {
     #if (!-e $request_filename) {
           #         return 404;
           # }
        fastcgi_pass 127.0.0.1:9000;
    #fastcgi_pass php5-fpm-sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
#      location / {
    #       try_files $uri $uri/ @codeigniter;
    #}
  # location @codeigniter {
  #         rewrite ^(.*) /index.php?$1 last;
  #  }

    # deny access to apache .htaccess files
    location ~ /'.ht
    {
        deny all;
    }
}    

那么,Nginx和Codeigniter之间这种误解背后的原因是什么呢?
提前谢谢。

您的配置中似乎没有规则告诉nginx在找不到文件时尝试向php发送请求。有一个注释掉的块,上面有try_files@codeigniter,几乎看起来像它。从理论上讲,这就是你想要nginx做的:

  1. 检查网址是否存在,如果确实提供它。
  2. 将其他所有内容发送到编码点火器并让它整理。

为此,这两个块应该足够了:

location / {
    # Check if a file exists, or route it to index.php.
    try_files $uri $uri/ /index.php;
}
location ~ '.php$ {     
   # for security, see http://forum.nginx.org/read.php?2,88845,page=3
   try_files $uri =404;
   fastcgi_split_path_info ^(.+'.php)(.*)$;
   fastcgi_pass 127.0.0.1:9000;
   fastcgi_index index.php;
   include fastcgi_params;
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

其他if受保护的块不应与这些块一起中断。