简体   繁体   English

使用 Nginx 中的命名位置处理 404 并返回自定义 404

[英]Handling 404's with Named Location in Nginx and returning custom 404's

I have a web service which serves dynamic images via Nginx web server.我有一个网络服务,它通过 Nginx 网络服务器提供动态图像。

Requests are handled by interpreting the URL structure and passing the initial 404 response to a Named Location which then matches the URL to various conditions to return an appropriate image.通过解释 URL 结构并将初始 404 响应传递给命名位置来处理请求,然后将 URL 与各种条件匹配以返回适当的图像。

Here is the basic config:这是基本配置:

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....
}

This works fine, but I also want to display custom 404 error page when non of the patterns are matched.这工作正常,但我还想在没有模式匹配时显示自定义 404 错误页面。

I thought I could handle this in my "custom_error.php" file:我想我可以在我的“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>

So that the Nginx config now looks like this:这样 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;
}

I added "fastcgi_intercept_errors on" so that Nginx does not intercept response codes greater than 300.我添加了“fastcgi_intercept_errors on”以便 Nginx 不会拦截大于 300 的响应代码。

Unfortunately, the 404 response return by "custom_error.php" is still intercepted by Nginx and returns it's own standard 404 response because, I guess, the "@imageHandlers" Named Location pass resets the initial 404 back to status 200 inside the block.不幸的是,“custom_error.php”返回的 404 响应仍然被 Nginx 拦截并返回它自己的标准 404 响应,因为我猜,“@imageHandlers”命名位置传递将初始 404 重置回块内的状态 200。

If I comment out the "if ($status == 404)" block from "custom_error.php", the custom error display fine BUT I get the status 200 status response code which is not correct.如果我从“custom_error.php”中注释掉“if ($status == 404)”块,自定义错误显示正常但我得到状态 200 状态响应代码,这是不正确的。

How can I achieve the custom 404 with the config I already set up?如何使用我已经设置的配置实现自定义 404?

Having recently faced a problem with custom errors from within a named location and stumbled upon this question.最近遇到了来自命名位置的自定义错误问题,并偶然发现了这个问题。

I think what is happening here is that when you reply with a 404, the fastcgi_intercept_errors on intercepts it, and you have a error_page 404 defined, possibly leading to a potential recursion.我认为这里发生的事情是,当您回复 404 时, fastcgi_intercept_errors on拦截它,并且您定义了error_page 404 ,这可能会导致潜在的递归。 In this case nginx will return its internal error.在这种情况下,nginx 将返回其内部错误。

I think you should not use fastcgi_intercept_errors , or alternatively you could define a different custom error in the @imageHandlers location, eg one that is not used ( error_page 417 /some_file.html ), so you stop inheriting the error_page defined from outside the location.我认为您不应该使用fastcgi_intercept_errors ,或者您可以在 @imageHandlers 位置定义不同的自定义错误,例如未使用的错误( error_page 417 /some_file.html ),这样您就不再继承从该位置外部定义的 error_page 。

In my case I had to add a recursive_error_pages on;在我的例子中,我必须添加一个recursive_error_pages on; too, and you might also need it, not sure.也,你可能也需要它,不确定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM