1

我使用CodeIgniter。CodeIgniter路由和404自定義錯誤

我使用routes.php文件根據url結構將某些網址路由到不同的文件。一切工作正常。

但是,幾個月前,我想我會添加一個自定義的404頁面。我做了,似乎工作正常。然而,我剛剛意識到我網站上的每個頁面(主頁除外)都會給出404錯誤的服務器響應,並向用戶顯示正確的頁面作爲自定義頁面!

我不知道這是怎麼回事,但它顯然是一場噩夢,因爲我現在沒有索引所有搜索引擎列表!域名http://citylightstours.com

routes.php文件

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 
/* 
| ------------------------------------------------------------------------- 
| URI ROUTING 
| ------------------------------------------------------------------------- 
| This file lets you re-map URI requests to specific controller functions. 
| 
| Typically there is a one-to-one relationship between a URL string 
| and its corresponding controller class/method. The segments in a 
| URL normally follow this pattern: 
| 
| example.com/class/method/id/ 
| 
| In some instances, however, you may want to remap this relationship 
| so that a different class/function is called than the one 
| corresponding to the URL. 
| 
| Please see the user guide for complete details: 
| 
| http://codeigniter.com/user_guide/general/routing.html 
| 
| ------------------------------------------------------------------------- 
| RESERVED ROUTES 
| ------------------------------------------------------------------------- 
| 
| There area two reserved routes: 
| 
| $route['default_controller'] = 'welcome'; 
| 
| This route indicates which controller class should be loaded if the 
| URI contains no data. In the above example, the "welcome" class 
| would be loaded. 
| 
| $route['404_override'] = 'errors/page_missing'; 
| 
| This route will tell the Router what URI segments to use if those provided 
| in the URL cannot be matched to a valid route. 
| 
*/ 

$route['default_controller'] = "content"; 
$route['en/(:num)/(:any)'] = "content/en/$1"; 
$route['de/(:num)/(:any)'] = "content/de/$1"; 
$route['es/(:num)/(:any)'] = "content/es/$1"; 
$route['it/(:num)/(:any)'] = "content/it/$1"; 
$route['ar/(:num)/(:any)'] = "content/ar/$1"; 
$route['404_override'] = ''; 


/* End of file routes.php */ 
/* Location: ./application/config/routes.php */ 

.htaccess文件:

<IfModule mod_rewrite.c> 
# Development 
    RewriteEngine On 
    RewriteBase/
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteCond $1 !^(index\.php|images|scripts|styles|vendor|robots\.txt) 
    RewriteRule ^(.*)$ index.php/$1 [L] 
</IfModule> 

DirectoryIndex index.php 
RewriteEngine on 
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|favicon\.ico) 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA] 

# ---------------------------------------------------------------------- 
# Better website experience for IE users 
# ---------------------------------------------------------------------- 

<IfModule mod_setenvif.c> 
    <IfModule mod_headers.c> 
    BrowserMatch MSIE ie 
    Header set X-UA-Compatible "IE=Edge,chrome=1" env=ie 
    </IfModule> 
</IfModule> 

<IfModule mod_headers.c> 
    Header append Vary User-Agent 
</IfModule> 


# ---------------------------------------------------------------------- 
# Webfont access 
# ---------------------------------------------------------------------- 

<FilesMatch "\.(ttf|otf|eot|woff|font.css)$"> 
    <IfModule mod_headers.c> 
    Header set Access-Control-Allow-Origin "*" 
    </IfModule> 
</FilesMatch> 

# ---------------------------------------------------------------------- 
# Proper MIME type for all files 
# ---------------------------------------------------------------------- 

# audio 
AddType audio/ogg      oga ogg 

# video 
AddType video/ogg      .ogv 
AddType video/mp4      .mp4 
AddType video/webm      .webm 

# Proper svg serving. Required for svg webfonts on iPad 
# twitter.com/FontSquirrel/status/14855840545 
AddType  image/svg+xml    svg svgz 
AddEncoding gzip      svgz 

# webfonts        
AddType application/vnd.ms-fontobject eot 
AddType font/truetype     ttf 
AddType font/opentype     otf 
AddType application/x-font-woff  woff 

# assorted types          
AddType image/x-icon     ico 
AddType image/webp      webp 
AddType text/cache-manifest   appcache manifest 
AddType text/x-component    htc 
AddType application/x-chrome-extension crx 
AddType application/x-xpinstall  xpi 
AddType application/octet-stream  safariextz 

# ---------------------------------------------------------------------- 
# gzip compression 
# ---------------------------------------------------------------------- 

<IfModule mod_deflate.c> 

<IfModule mod_setenvif.c> 
    <IfModule mod_headers.c> 
    SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s,?\s(gzip|deflate)?|X{4,13}|~{4,13}|-{4,13})$ HAVE_Accept-Encoding 
    RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding 
    </IfModule> 
</IfModule> 

<FilesMatch "^(?!.*\.ogg$|.*\.ogv$|.*\.mp4$).+" > 

# html, txt, css, js, json, xml, htc: 
<IfModule filter_module> 
    FilterDeclare COMPRESS 
    FilterProvider COMPRESS DEFLATE resp=Content-Type /text/(html|css|javascript|plain|x(ml|-component))/ 
    FilterProvider COMPRESS DEFLATE resp=Content-Type /application/(javascript|json|xml|x-javascript)/ 
    FilterChain  COMPRESS 
    FilterProtocol COMPRESS change=yes;byteranges=no 
</IfModule> 
</FilesMatch> 

# webfonts and svg: 
    <FilesMatch "\.(ttf|otf|eot|svg)$" > 
    SetOutputFilter DEFLATE 
    </FilesMatch> 
</IfModule> 

# ---------------------------------------------------------------------- 
# Expires headers (for better cache control) 
# ---------------------------------------------------------------------- 

<IfModule mod_expires.c> 
    ExpiresActive on 

# Perhaps better to whitelist expires rules? Perhaps. 
    ExpiresDefault       "access plus 1 month" 

# cache.appcache needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5) 
    ExpiresByType text/cache-manifest  "access plus 0 seconds" 

# your document html 
    ExpiresByType text/html     "access plus 0 seconds" 

# data 
    ExpiresByType text/xml     "access plus 0 seconds" 
    ExpiresByType application/xml   "access plus 0 seconds" 
    ExpiresByType application/json   "access plus 0 seconds" 

# rss feed 
    ExpiresByType application/rss+xml  "access plus 1 hour" 

# favicon (cannot be renamed) 
    ExpiresByType image/x-icon    "access plus 1 week" 

# media: images, video, audio 
    ExpiresByType image/gif     "access plus 1 month" 
    ExpiresByType image/png     "access plus 1 month" 
    ExpiresByType image/jpg     "access plus 1 month" 
    ExpiresByType image/jpeg    "access plus 1 month" 
    ExpiresByType video/ogg     "access plus 1 month" 
    ExpiresByType audio/ogg     "access plus 1 month" 
    ExpiresByType video/mp4     "access plus 1 month" 
    ExpiresByType video/webm    "access plus 1 month" 

# htc files (css3pie) 
    ExpiresByType text/x-component   "access plus 1 month" 

# webfonts 
    ExpiresByType font/truetype    "access plus 1 month" 
    ExpiresByType font/opentype    "access plus 1 month" 
    ExpiresByType application/x-font-woff "access plus 1 month" 
    ExpiresByType image/svg+xml    "access plus 1 month" 
    ExpiresByType application/vnd.ms-fontobject "access plus 1 month" 

# css and javascript 
    ExpiresByType text/css     "access plus 2 months" 
    ExpiresByType application/javascript "access plus 2 months" 
    ExpiresByType text/javascript   "access plus 2 months" 

    <IfModule mod_headers.c> 
    Header append Cache-Control "public" 
    </IfModule> 

</IfModule> 

# ---------------------------------------------------------------------- 
# ETag removal 
# ---------------------------------------------------------------------- 

FileETag None 

# ---------------------------------------------------------------------- 
# Stop screen flicker in IE on CSS rollovers 
# ---------------------------------------------------------------------- 

# The following directives stop screen flicker in IE on CSS rollovers - in 
# combination with the "ExpiresByType" rules for images (see above). If 
# needed, un-comment the following rules. 

# BrowserMatch "MSIE" brokenvary=1 
# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1 
# BrowserMatch "Opera" !brokenvary 
# SetEnvIf brokenvary 1 force-no-vary 

RewriteEngine On 
RewriteCond %{HTTP_HOST} !^citylightstours\.com$ [NC] 
RewriteRule ^(.*)$ http://citylightstours.com/$1 [R=301,L] 
RewriteCond %{HTTP_USER_AGENT} libwww-perl.* 
RewriteRule .* ? [F,L] 

我有一個MY_Router.php文件來處理客戶404頁,不知這是否設置404 HTTP狀態不正確?

MY_Router.php文件:

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 

class MY_Router extends CI_Router { 

    var $error_controller = 'error'; 
    var $error_method_404 = 'error_404'; 

    function My_Router() 
    { 
     parent::CI_Router(); 
    } 

    // this is just the same method as in Router.php, with show_404() replaced by $this->error_404(); 
    function _validate_request($segments) 
    { 
     // Does the requested controller exist in the root folder? 
     if (file_exists(APPPATH.'controllers/'.$segments[0].EXT)) 
     { 
      return $segments; 
     } 

     // Is the controller in a sub-folder? 
     if (is_dir(APPPATH.'controllers/'.$segments[0])) 
     {  
      // Set the directory and remove it from the segment array 
      $this->set_directory($segments[0]); 
      $segments = array_slice($segments, 1); 

      if (count($segments) > 0) 
      { 
       // Does the requested controller exist in the sub-folder? 
       if (! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT)) 
       { 
        return $this->error_404(); 
       } 
      } 
      else 
      { 
       $this->set_class($this->default_controller); 
       $this->set_method('index'); 

       // Does the default controller exist in the sub-folder? 
       if (! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT)) 
       { 
        $this->directory = ''; 
        return array(); 
       } 
      } 

      return $segments; 
     } 

     // Can't find the requested controller... 
     return $this->error_404(); 
    } 

    function error_404() 
    { 
     $this->directory = ""; 
     $segments = array(); 
     $segments[] = $this->error_controller; 
     $segments[] = $this->error_method_404; 
     return $segments; 
    } 

    function fetch_class() 
    { 
     // if method doesn't exist in class, change 
     // class to error and method to error_404 
     $this->check_method(); 

     return $this->class; 
    } 

    function check_method() 
    { 
     $ignore_remap = true; 

     $class = $this->class; 
     if (class_exists($class)) 
     { 
      // methods for this class 
      $class_methods = array_map('strtolower', get_class_methods($class)); 

      // ignore controllers using _remap() 
      if($ignore_remap && in_array('_remap', $class_methods)) 
      { 
       return; 
      } 

      if (! in_array(strtolower($this->method), $class_methods)) 
      { 
       $this->directory = ""; 
       $this->class = $this->error_controller; 
       $this->method = $this->error_method_404; 
       include(APPPATH.'controllers/'.$this->fetch_directory().$this->error_controller.EXT); 
      } 
     } 
    } 

    function show_404() 
    { 
     include(APPPATH.'controllers/'.$this->fetch_directory().$this->error_controller.EXT); 
     call_user_func(array($this->error_controller, $this->error_method_404)); 
    } 

} 

/* End of file MY_Router.php */ 
/* Location: ./system/application/libraries/MY_Router.php */ 

能有人請幫助?

感謝

+0

我認爲這是找到頁面並返回,但設置的404的服務器響應代碼會在哪裏把它設置在笨???? –

回答

0

你的路線需要修復: -

$route['en/(:num)/(:any)'] = "content/en/$1"; 
$route['de/(:num)/(:any)'] = "content/de/$1"; 
$route['es/(:num)/(:any)'] = "content/es/$1"; 
$route['it/(:num)/(:any)'] = "content/it/$1"; 
$route['ar/(:num)/(:any)'] = "content/ar/$1"; 

在此有一個讀 -

http://www.codeigniter.com/userguide2/general/routing.html

根據你的路由你必須爲每種語言的控制器。例如(enController,deController,esController等),我假設你沒有,你只是有一個內容控制器。

您正在尋找可以在這裏找到的響應: -

https://github.com/bcit-ci/CodeIgniter/wiki/URI-Language-Identifier

+0

嗨codenathan,感謝您花時間回覆。我閱讀那篇文章,看不到我的路由有任何問題 - 它鏈接到內容類和語言方法。我不認爲它指定了不同的內容控制器 - 只有一個控制器內有不同的方法...?在任何情況下,我刪除了參考路線的語言方面,但我仍然得到404服務器響應和正確的頁面顯示爲人類自定義頁面....任何想法發生了什麼事? –

+0

對不起,我錯誤地閱讀,你可以發佈你的內容控制器代碼? – codenathan

+0

嗨codenathan,我可以但我不認爲它有任何與我的內容控制器。所有工作正常,因爲它正確進行並從數據庫獲取正確的頁面數據並正確顯示它。問題是它顯示它的http狀態是404而不是200.我有一個自定義錯誤頁面,並認爲它可能與我的MY_Router.php文件有關,以便執行此自定義404。 MYRouter代碼... –