CodeIgniter nginx 针对 i8ln URL 的重写规则

CodeIgniter nginx 针对 i8ln URL 的重写规则

我正在开发 Vagrant 盒子(带有 nginx 1.8.1 的 Ubuntu TLS 14 和带有 php-fpm 的 PHP 5.6)上测试使用 CodeIgniter 构建的网站,但 CodeIgniter 似乎失败了nginx

经过多次尝试和错误,以及收集了其他类似问题的零碎信息后,我能够进行部分重定向。此网站的 URL 结构基于区域 ISO 代码,例如:因此,如果我从美国浏览网站,它会重定向到,如果从欧洲浏览,则会http://example.com/REGION/language重定向到。通过使用 GeoIP 数据库和 CodeIgniter 301 重定向,至少有 4-5 种这样的组合。http://example.com/US/enhttp://example.com/EU/en

我的nginx配置如下:

# 默认服务器配置
服务器 {

    听 80 默认服务器;
    听[::]:80默认服务器;

    根目录/var/www/html;

    # 如果您使用 PHP,请将 index.php 添加到列表中
    索引 index.php index.html index.htm index.nginx-debian.html;

    服务器名称 _;

    地点 / {

        # 首先尝试以文件形式提供请求,然后
        # 作为目录,然后回退到显示 404。
        尝试文件$uri $uri/ =404;
        #try_files $uri /index.html index.php =404;
        #try_files $uri $uri/ /index.php;
    }

    # 将 PHP 脚本传递给监听 127.0.0.1:9000 的 FastCGI 服务器
    #
    位置 ~ \.php$ {

        # 正则表达式将 $uri 拆分为 $fastcgi_script_name 和 $fastcgi_path
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        # 在传递 PHP 脚本之前,检查它是否存在
        尝试文件$fastcgi_script_name =404;

        # 绕过 try_files 重置 $fastcgi_path_info 的事实
        # 参见:http://trac.nginx.org/nginx/ticket/321
        设置$path_info $fastcgi_path_info;
        fastcgi_param PATH_INFO $path_info;

        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index索引.php;

        #FastCGI 配置
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_param REQUEST_METHOD $request_method;
        fastcgi_param 内容类型 $内容类型;
        fastcgi_param 内容长度 $内容长度;

        fastcgi_param 脚本名称 $fastcgi_script_name;
        fastcgi_param REQUEST_URI $request_uri;
        fastcgi_param DOCUMENT_URI $document_uri;
        fastcgi_param DOCUMENT_ROOT $document_root;
        fastcgi_param SERVER_PROTOCOL $服务器协议;
        fastcgi_param HTTPS $https if_not_empty;

        fastcgi_param GATEWAY_INTERFACE CGI/1.1;
        fastcgi_param 服务器软件 nginx/$nginx_version;

        fastcgi_param REMOTE_ADDR $remote_addr;
        fastcgi_param REMOTE_PORT $远程端口;
        fastcgi_param SERVER_ADDR $server_addr;
        fastcgi_param SERVER_PORT $服务器端口;
        fastcgi_param SERVER_NAME $服务器名称;

        # 仅限 PHP,如果 PHP 是使用 --enable-force-cgi-redirect 构建的,则需要此配置
        fastcgi_param REDIRECT_STATUS 200;
    }

    # 如果 Apache 的文档根目录与 nginx 的一致,则拒绝访问 .htaccess 文件
    位置 ~ /\.ht {
        全部否认;
    }

    位置/示例{

        根目录/var/www/html/;
        索引索引.php;

        位置 ~ ^/example/(.+\.php)$ {

            客户端最大主体大小4M;
            客户端主体缓冲区大小128k;
            根目录/var/www/html/;
            尝试文件$uri =404;
            fastcgi_split_path_info ^(.+\.php)(.*)$;

            # 使用 php5-fpm:
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index索引.php;
            包括/etc/nginx/fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }

        位置 ~* ^/example/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)) {

            根目录/var/www/html/;
        }

        # CI 重写规则
        如果 ($host ~* ^www\.(.*)) {

            设置$host_without_www $1;
            重写 ^/(.*)$ $scheme://$host_without_www/$1 永久;
        }

        # 规范化 codeigniter url 端点,如果你的默认控制器不是“welcome”,你应该更改以下内容
        如果 ($request_uri ~* ^(/pages(/view)?|/index(.php)?)/?$) {

            重写 ^(.*)$ / 永久;
        }

        # 从所有控制器中删除尾随的“索引”
        如果 ($request_uri ~* index/?$) {

            重写 ^/(.*)/index/?$ /$1 永久;
        }

        # 删除尾部斜杠(防止 SEO 重复内容问题)
        如果(!-d $请求文件名){

            重写 ^/(.+)/$ /$1 永久;
        }

        # 删除对“系统”文件夹的访问权限,同时允许“System.php”控制器
        如果 ($request_uri ~* ^/system) {

            最后重写 ^/(.*)$ /index.php?/$1;
            休息;
        }

        # 除非请求的是有效文件(图像、js、css 等),否则发送到 bootstrap
        如果(!-e $请求文件名){

            最后重写 ^/(.*)$ /index.php?/$1;
            休息;
        }

        # 捕获全部
        错误页面 404 /index.php;
    }

}

因此,当我从 localhost 浏览它时,如果在 GeoIP 数据库中找不到有效位置,http://192.168.33.15/example/它会重定向到默认位置,其中是http://192.168.33.15/example/INT/enexamplenginxroot。到目前为止没有错误,但是nginx没有正确重定向并解释INT/en为文件夹,因此弹出错误404 Not Found

我浏览过很多论坛帖子服务器故障Stackchange和其他在线资源,但它们都没有任何帮助,因为 CodeIgniter 或nginx网站或者这似乎都是询问的正确地方。

答案1

找到了一个更简单的解决方案。代码点火器在后台执行干净的 URL;在 Apache 中,此重写的工作方式是将每个请求发送为,http://example.com/index.php?/controller/method然后由代码点火器所以你config.php应该看起来像

$config['base_url'] = 'http://example.com'
$配置['index_page'] = '';
$config['uri_protocol'] = '请求URI';

为了实现同样的目标nginx你必须以相同的方式重写每个请求。微调我的nginx配置为:

位置/示例{

    根目录/var/www/html/;
    索引索引.php;

    位置 ~ ^/example/(.+\.php)$ {

        fastcgi_buffer_大小 128k;
        fastcgi_缓冲区 256 4k;
        fastcgi_busy_buffers_大小:256k;
        fastcgi_temp_file_write_size 是 256k;
        根目录/var/www/html/;
        包括/etc/nginx/snippets/fastcgi-php.conf;
    }

    位置 ~* ^/example/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)) {
        根目录/var/www/html/;
    }

    # 强制使用 SSL
    如果 ($scheme = http) {
        返回 301 https://$host$request_uri;
    }

    # CI 重写规则
    如果 ($host ~* ^www\.(.*)) {
        设置$host_without_www $1;
        重写 ^/(.*)$ $scheme://$host_without_www/$1 永久;
    }

    如果 ($request_uri ~* ^(/example/(US|EU|INT)/(en|de)(.*))?$) {
        最后重写 ^/(.*)$ /example/index.php?/$1;
    }

    如果 ($request_uri ~* ^(/example/(US|EU|INT)/(en|de)/(.*))?$) {
        最后重写 ^/(.*)$ /example/index.php?/$1;
    }

    # 捕获全部
    错误页面 404 /index.php;
}

缺失的环节存在于nginx 重写调试日志因此,如果你想了解你的重写规则以及它们是否与你的规则集匹配,请将其添加到你的nginx配置:

服务器{
  ...
  重写_登录;
  错误日志 /var/log/nginx/error.log 信息;
  ...
}

nginx将为您提供与您的 PCRE 正则表达式匹配或不匹配的每个请求日志。从这里开始,您可以调整配置。我必须example在前面添加路径(目录)nginx配置文件以使重写规则按预期工作。

相关内容