在Nginx中处理具有命名位置的404,并返回自定义404

时间:2019-04-24 08:33:36

标签: php nginx error-handling url-rewriting

我有一个Web服务,可通过Nginx Web服务器提供动态图像。

通过解释URL结构并将初始404响应传递到“命名位置”来处理请求,然后该命名位置将URL与各种条件进行匹配以返回适当的图像。

这是基本配置:

error_page 404 = @imageHandlers;

location @imageHandlers {
  #= Match pattern 1 =========
  if ($uri ~* "^/(some_pattern1)$") {
    set $x = $1;
    rewrite .* "image_handler_type1.php?q=$x" last;
  }

  #= Match pattern 2 =========
  if ($uri ~* "^/(some_pattern2)$") {
    set $x = $1;
    rewrite .* "image_handler_type2.php?q=$x" last;
  }

  etc....
}

这很好用,但我也想在不匹配任何模式时显示自定义404错误页面。

我认为我可以在“ custom_error.php”文件中进行处理:

<?php
$status = $_GET["status"];
if ($status == 404) {
  header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
}
?>
<html>
<head><title><?php echo $status;?></title></head>
<body bgcolor="white">
<center><h1>Error <?php echo $status;?></h1></center>
</body>
</html>

因此Nginx配置现在看起来像这样:

fastcgi_intercept_errors on;

error_page 404 = @imageHandlers;

location @imageHandlers {
  #= Match pattern 1 =========
  if ($uri ~* "^/(some_pattern1)$") {
    set $x = $1;
    rewrite .* "image_handler_type1.php?q=$x" last;
  }

  #= Match pattern 2 =========
  if ($uri ~* "^/(some_pattern2)$") {
    set $x = $1;
    rewrite .* "image_handler_type2.php?q=$x" last;
  }

  etc....

  #= Otherwise display custom 404 =========
  rewrite .* "/custom_error.php?status=404" last;
}

我添加了“ fastcgi_intercept_errors on”,以便Nginx不会拦截大于300的响应代码。

不幸的是,“ custom_error.php”返回的404响应仍被Nginx截获,并返回其自己的标准404响应,因为,我猜,“ @ imageHandlers”命名位置传递将初始404重置为状态404。

如果我从“ custom_error.php”中注释掉了“ if($ status == 404)”块,则自定义错误显示会很好,但是我得到的状态200状态响应代码不正确。

如何使用已经设置的配置实现自定义404?

1 个答案:

答案 0 :(得分:0)

最近在命名位置遇到自定义错误的问题,偶然发现了这个问题。

我认为这里发生的是,当您用404答复时,fastcgi_intercept_errors on截获了它,并且您定义了error_page 404,可能导致潜在的递归。在这种情况下,nginx将返回其内部错误。

我认为您不应该使用fastcgi_intercept_errors,或者您可以在@imageHandlers位置中定义其他自定义错误,例如一个未使用的(error_page 417 /some_file.html),因此您停止从该位置外部继承定义的error_page。

在我的情况下,我也必须添加一个recursive_error_pages on;,您不确定也可能需要它。