当CodeIgniter遇到Nginx报404错误的解决办法

由于CodeIgniter当初是设计在apache的,而apache对pathinfo是支持比较好的,所以一切都很nice。但是当你把写好的代码放到nginx上,傻眼了,可能出了CodeIgniter的welcom之外,其他都是404错误。而我惊奇的发现,CodeIgniter的官方文档竟然对在Nginx上的配置只字不提。而你百度”CodeIgniter Nginx 404”又能搜到一堆一堆的文章,奇葩的是几乎每个文档的配置方法貌似还不大一样。如果你搞好了还罢,搞不好就是配几个晚上都搞不定,像我一样。(本文服务器环境:CentOS,nginx-1.4.7,php-5.4.24,CodeIgniter3.0.2--当前最新版本)

404错误的原因

原因是默认Nginx不支持pathinfo这种格式,当你浏览器里输入http:\xxx.xxx.com\index.php\pages\home的时候,Nginx会认为你要访问index.php目录下的pages文件夹里的home,所以会报404 not found错误。

解决方法

解决方法肯定是要修改服务器的重定向规则,大概有两种思路,一种是改nginx安装目录里的nginx.conf文件,如果你用了虚拟主机的话就去nginx安装目录下的vhosts下找对应的*.conf更改即可。另外一种思路修改CI目录下的.htaccess文件,参见:http://blog.csdn.net/freshlover/article/details/8977111

本文是第一种思路。在修改之前先来看下原始的conf文件:

{
       listen 80;
       server_name 1.abc.com 2.abc.com;
        root /a/domains/1.abc.com/public_html;
        index index.html index.htm index.shtml index.php;

        error_page  404               /404.html;
    #Custom rules Start
        #Custom rules End
    location = /500.html {
        root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        fastcgi_pass   unix:/dev/shm/php.sock;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        access_log     /a/apps/nginx/logs/1.abc.com.access.log main;
    }

    location ~ /\.ht {
        deny  all;
    }
}

PS:上面为了隐私,我把server_name改为1.abc.com了,这个对应自己的server_name.

下面介绍修改方法,在修改conf前切记将自己的conf,cp为conf.back备份一份。

下面为修改方法:

1,修改php支持pathinfo

再修改conf之前,找到php的php.ini文件(可能在php安装目录的etc目录也可能在lib文件夹下,看自己的配置),搜索:cgi.fix_pathinfo

将注释放开,并置为1:cgi.fix_pathinfo=1

2,修改conf之前有个问题要明确,那就是CI的根目录 是不是web的root目录,如果是的话,如下修改:

只需要增加如下即可:

在location ~ .php$之前增加一段:

     if (!-e $request_filename) {
          rewrite ^.*$ /index.php last;
     }

这个意思是,如果你浏览器里要访问的文件不存在时,会自动路由至web根目录下的index.php进行访问。

当然上面这段话也可以用下面的来代替:

    location / {
        try_files $uri $uri/ /index.php;
    }

完整的配置为:

server{
    listen 80;
    server_name 1.sod90.com app.sod90.com;
    root /a/domains/1.sod90.com/public_html;
    index index.html index.htm index.shtml index.php;

    error_page  404               /404.html;
    #Custom rules Start
        #Custom rules End
        location = /500.html {
        root   /usr/share/nginx/html;
    }

    #location / {
    #    try_files $uri $uri/ /index.php;
    #}

     if (!-e $request_filename) {
          rewrite ^.*$ /city52/index.php last;
     }

    location ~ \.php$ {
        fastcgi_pass   unix:/dev/shm/php.sock;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        access_log     /a/apps/nginx/logs/app.sod90.com.access.log main;
    }

    location ~ /\.ht {
        deny  all;
    }
}

注意:上面的try_files完全可以代替rewrite,参见链接

除了加这个重定向之外,conf里不需要再加任何奇奇怪怪的东西。

然后检查CI的config文件里以下三个参数:

$config[‘base_url‘] = ‘http://1.abc.com/‘;
$config[‘index_page‘] = ‘‘;
$config[‘uri_protocol‘]    = ‘REQUEST_URI‘;

这三个参数比较关键,其中第一个是web根目录对应的域名 ,index_page要为”,不要为默认值 ‘index.php’.

经过以上设置就ok了,url地址里不需要写index.php了。

延伸

现在考虑这种情况,如果一个后台,分支持app和web的,有时候用不同的框架也是在所难免。把所有框架都放在根目录下也不太好看。如果我的CI的根目录不是web的根目录,而是如public_html下的xxx文件夹,此时只需将conf里的try_files语句里路由的/index.php改为/xxx/index.php即可。如下:

    location / {
        try_files $uri $uri/ /xxx/index.php;
    }

再CI的config.php里,写成

$config[‘base_url‘] = ‘http://1.abc.com/‘;

或者:

$config[‘base_url‘] = ‘http://app.sod90.com/xxx/‘;

都是可以的,只要路由对了,就没问题。但是为了保险起见,base_url如后者比较好,然后url里就不要再带index.php了。两者的区别还体现在当使用CI的函数如base_url()时得到的值将会不一样。参考链接

附一个国外比较靠谱点的链接:

http://stackoverflow.com/questions/8182868/nginx-configuration-avoid-codeigniter-rewrite-rules

CI的多目录:http://blog.sina.com.cn/s/blog_6ec2ae900101kbx9.html

补充说明,一般来说conf里如下三句话是关键:

    fastcgi_param  PATH_INFO $fastcgi_path_info;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param  PATH_TRANSLATED $document_root$fastcgi_path_info;

但是我的conf里只用了下面一句:

fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 12:28:31

当CodeIgniter遇到Nginx报404错误的解决办法的相关文章

有关百度一键分享链接到微信朋友圈无法打开网页,报404错误的解决办法,from=timeline&isappinstalled=0,和伪静态规则有关

最近有好友反映用百度一键分享,分享网页链接到微信朋友圈的时候,发现链接无法打开,提示无法找到该页404错误,同样分享到QQ.微博等链接 能正常访问,这么明显的错误,百度和腾讯应该不会忽略吧. 接报后,我专门分析了一遍他公司的网站,确实是微信朋友圈无法分享网站链接.但是通过微信扫一扫能正常浏览网页,点击分享到朋友圈后,在  从朋友圈去访问的时候,提示无法找到该页,报404错误. 经反复检测,排除了分享代码的问题,和服务器配置问题.我开始怀疑伪静态规则,开启URL重写造成的,我关掉了伪静态,让网页形

上传大文件报404错误的解决办法

在Windows2008下,如果上传比较大的文件,可能会出现404错误,(请求筛选模块被配置为拒绝超过请求内容长度的请求). 可通过如下方法解决: 打开URTracker根目录下的web.config文件,找到<system.webServer>一节,加入如下配置即可: <security> <requestFiltering > <requestLimits maxAllowedContentLength="1024000000" >&

Adobe Dreamweaver CC MySQL连接 报404错误的解决方法

Adobe Dreamweaver CC MySQL连接时总报404报错,并给以下两个提示: 1) 在该服务器机器上没有测试服务器运行. 2) 为该站点指定的测试服务器没有映射到http://localhost/_mmServerScripts/MMHTTPDB.phpURL.请确认url前缀映射到了你站点的根上. 网上翻了一堆网站,折腾了两三天,发现可以按如下方法解决: 1)首先要在http://localhost/security/index.php配置mysql的访问密码(我用的是XAMP

关于SSIS批量抽取Excel文件报0x80004005错误的解决办法

原文:关于SSIS批量抽取Excel文件报0x80004005错误的解决办法 标题: Microsoft Visual Studio ------------------------------ Package [连接管理器“Excel 连接管理器”] 出错: SSIS 错误代码 DTS_E_OLEDBERROR.出现 OLE DB 错误.错误代码: 0x80004005. 已获得 OLE DB 记录.源:“Microsoft JET Database Engine” Hresult: 0x80

Intellij IDEA + Tomcat 出现 HTTP status 404错误的解决办法

最近要做POC,接了个老项目改,使用war exploded部署到本机的Tomcat(8.5版) 通过Intellij IDEA启动Tomcat的时候发现系统的登录页面出现HTTP-status-404错误,这时直接在浏览器中打开http://localhost:8080则能打开Tomcat的欢迎页面,说明Tomcat起来了,但是没有正确加载webapps目录下的东西. 更奇怪的是,通过Tomcat的bin目录下的启动脚本就可以正常启动,无论是双击startup.bat还是在该目录的cmd下使用

yum安装源是出现报冲突错误,解决办法

起因,是打算在linux6.5服务器上安装 dell的osma 管理工具 在安装先决包时出现错误 报错如下: yum install libcmpiCppImpl0已加载插件:aliases, changelog, downloadonly, kabi, presto, refresh-packagekit, security, tmprepo, verify, versionlockLoading support for kernel ABI设置安装进程解决依赖关系--> 执行事务检查--->

spring mvc 4.1 返回json报406错误的解决办法

浏览器访问,报 The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers. 解决办法,检查springmvc的配置文件中有无 <mvc:annotation-driven />

关于tomcat启动服务单独启动时ngrok报500错误的解决办法

去年开通了微信公众号,每次都是启动eclipse,然后用eclipse里的tomcat来启动服务,然后启动ngrok,这样微信服务就算启动成功了,如下图: ,公众号可以正常返回数据,ngrok也返回的200状态码.但是每次单独用tomcatbin目录下的startup.bat批处理命令启动后,然后再访问,ngrok就会提示500服务器内部错误,但是没有更具体的提示信息. 解决办法:把发送微信请求的地址考出来,再浏览器里执行,浏览器会给出更具体的提示,比如我的微信公号访问的地址是: http://

AspNet Mvc 路由解析中添加.html 等后缀 出现404错误的解决办法

使用Mvc 有时候我们希望,浏览地址以.html .htm 等后缀名进行结尾. 于是我们就在RouteConfig 中修改路由配置信息,修改后的代码如下 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}.html", defaults: new { controller =