有关mod_rewrite,子域和codeigniter的问题

时间:2013-04-12 04:45:34

标签: .htaccess codeigniter mod-rewrite subdomain

我在example.com/ci上安装了codeigniter。 我有一个子域名foo.example.com。 foo子域的文档根目录设置为home / public_html / ci。

我在.htaccess中使用以下规则将foo.example.com的请求发送到example.com/ci/city/foo。

 RewriteCond %{HTTP_HOST} !^(www)\. [NC]
 RewriteCond %{HTTP_HOST} ^(.*)\.example\.com [NC]
 RewriteRule (.*) http://example.com/ci/city/%1/$1 [L]

除了地址栏网址从foo.example.com更改为example.com/ci/city/foo之外,这一切都像我想要的那样。我希望它仍然是foo.example.com。 RewriteRule中没有R = 301(以前是我删除了它)。 .htaccess文件位于ci /文件夹中,规则高于所有codeigniter内容。

重定向工作完美,网址仍为foo.example.com(Jon Lin的回答)

RewriteCond %{HTTP_HOST} !^(www)\. [NC]
 RewriteCond %{HTTP_HOST} ^(.*)\.example\.com [NC]
 RewriteCond %{REQUEST_URI} !/city/
 RewriteRule (.*) /city/%1/$1 [L]

但是在城市控制器中调用了codeigniter默认控制器而不是foo方法。

感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

当您的重写规则的目标中包含http://example.com时,无论是否使用R标志,都会隐含302重定向。您需要根据子域的文档根提供URI路径,因此我假设您需要以下内容:

RewriteCond %{HTTP_HOST} !^(www)\. [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com [NC]
RewriteCond %{REQUEST_URI} !/city/
RewriteRule (.*) /city/%1/$1 [L]

如果子域的文档根位于/ci/目录中。

另一种选择是使用P标志来反向代理请求:

RewriteCond %{HTTP_HOST} !^(www)\. [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com [NC]
RewriteRule (.*) http://example.com/ci/city/%1/$1 [L,P]

答案 1 :(得分:1)

你的里程可能会因此而有所不同(可能需要巧妙地适应你的服务器和条件),但在我的Mac上进行一些测试,这是我取得的成功:

目录结构

public_html/
  ci/
    application/
    system/
    .htaccess
    index.php

我假设您的根public_html目录中有其他内容。所以我让.htaccess将它放在ci目录中,关注与CodeIgniter相关的东西。

的.htaccess

DirectoryIndex index.php

RewriteEngine on

RewriteCond %{HTTP_HOST} ^(.*)\.ciwildsub\.dev [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php/city/%1/$1 [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]

这是相当自我解释的,但第一个块是您的子域检查。我不打扰排除www,但你可能想(正如我所说,你的里程可能会有所不同)。第二个块是标准CodeIgniter index.php删除。

这些规则仅适用于sub.example.comexample.com/ci/网址,因为正如我所说的,我认为你的根有不应该被重写打扰的内容。

CodeIgniter配置

$config['uri_protocol'] = 'PATH_INFO';

由于Apache处理像example.com/index.php/controller/method这样的URL的方式,它会绕过index.php并像处理任何其他目录段一样处理它。此外,mod_rewrite不一定在<{1}}标记处停止 - 它会在此时停止处理.htaccess,通过RewriteRule,然后通过.htaccess运行该URL。设置[L]有助于确保CodeIgniter正确地提取当前URI,并且我们的.htaccess不会卡在验证循环中。

我会注意到,我对我在RewriteLog输出中看到的内容并不完全满意 - 是进一步优化这一点的方法,我只是不确定它(我今天完成了这个修补!)。很抱歉,如果这里的任何解释有点不合适 - 我不是服务器管理员或mod_rewrite专家,我只是很乐意修补这个。如果我设法找到更好的解决方案,我一定会更新。


看起来END flag对于这样的情况(防止PATH_INFO循环)是完美的,但它仅在Apache 2.3.9+中可用。搜索仍在继续。

答案 2 :(得分:1)

我使用以下重写规则

使其正常工作
   RewriteCond %{HTTP_HOST} !^(www)\. [NC]
 RewriteCond %{HTTP_HOST} ^(.*)\.example\.com [NC]
 RewriteCond %{REQUEST_URI} !/city/
 RewriteRule (.*) /city/%1/$1 [L]

并设置

$config['uri_protocol'] = 'ORIG_PATH_INFO';
在codeigniter配置文件中

。感谢您的帮助。

答案 3 :(得分:0)

这对我有用

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /file_path/to/subdomain
    RewriteCond $1 !^(index\.php|images|robots\.txt)
    RewriteRule ^(.*)$ /index.php/$1 [L]
    RewriteCond %{REQUEST_URI} ^application.*
        RewriteRule ^(.*)$ /index.php?/$1 [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.php?/$1 [L]
    </IfModule>

    <IfModule !mod_rewrite.c>
        ErrorDocument 404 /index.php
    </IfModule>