多语言自定义404 htaccess规则导致重定向循环

时间:2014-07-10 09:39:50

标签: apache .htaccess mod-rewrite redirect

我正在多语言网站上工作,我需要为每种语言设置自定义404页面。我在.htaccess中有以下规则,这些规则不能正常工作:

RewriteCond %{REQUEST_URI} !^/(ie)(/|$) [NC]
ErrorDocument 404 http://www.domain.com/ie/404/

RewriteCond %{REQUEST_URI} !^/(se)(/|$) [NC]
ErrorDocument 404 http://www.domain.com/se/404/

RewriteCond %{REQUEST_URI} !^/(nl)(/|$) [NC]
ErrorDocument 404 http://www.domain.com/nl/404/

#last rule becomes default
RewriteCond %{REQUEST_URI} !^/(en)(/|$) [NC]
ErrorDocument 404 http://www.domain.com/uk/404/

RewriteRule ^([a-z]{2})/404(/)?$ index.php?controller=utils&method=view404&lang=$1 [L]
RewriteRule ^([a-z]{2})/404.html$ index.php?controller=utils&method=view404&lang=$1 [L]

我认为问题可能与!在RewriteCond,然而删除这没有帮助。如果我访问domain.com/4t3409t0(一个不存在的页面),这与最后一个RewriteCond匹配并重定向到domain.com/uk/404(实际上可以正常工作)。

但是,如果我尝试使用域名(例如domain.com/ie/wfnwio),它会尝试重定向到domain.com/ie/404(应该这样),而我会陷入重定向循环。

所以看起来当满足最后一个RewriteCond时,重写会起作用,但对于其他任何一个,它们都会失败。

我只需要为每种语言设置ErrorDocument URL,将现有内容重定向到404的功能已经存在。

感谢您提供任何意见,

詹姆斯

3 个答案:

答案 0 :(得分:3)

我建议用以下内容替换所有内容:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(ie|se|nl)/ $1/404 [R=404,L]

<强>解释

  • 这三个条件检查所请求的文件或文件夹是否不存在
  • 规则会检查请求的网址是从三个国家/地区中的一个开始,然后是/,将国家/地区代码捕获到第1组
  • 重定向到Group1 / 404,例如ie/404带有404代码

答案 1 :(得分:0)

我从this comment得到了一个想法。 在.htacces文件中:

ErrorDocument 404 "<script>window.location.href='/error.php?page='+window.location.href;</script>" 

在error.php (在根目录中):

<?php
$lg="en";  // default 404 page language
$langs=array("az","tr","ru","en");

if(isset($_GET['page'])){
    $page=$_GET['page'];
    foreach($langs as $lang){ 
    if(strpos($page,"lang=".$lang)!==false) { $lg=$lang; break; }
    }
} 
echo '<meta http-equiv="refresh" content="0;URL=/index.php?controller=utils&method=view404&lang='.$lg.'" />'; 
exit;

答案 2 :(得分:-2)

我认为我遇到的问题是RewriteCond不正确。但是我找到了一种解决方法,因为PHP将语言存储在会话变量中。

ErrorDocument 404 http://www.domain.com/404/

RewriteRule ^404(/)?$ index.php?controller=utils&method=view404 [L]
RewriteRule ^([a-z]{2})/404(/)?$ index.php?controller=utils&method=view404&lang=$1 [L]
RewriteRule ^([a-z]{2})/404.html$ index.php?controller=utils&method=view404&lang=$1 [L]

我的解决方法只是使用domain.com/404作为默认设置,然后在可能的情况下通过会话设置语言,或者如果没有,则加载UK 404页面。

如果在查询字符串中设置了语言变量,则使用第二和第三次重写规则传递它。