52

我有一个由 Unicorn 托管的 Sinatra 应用程序,前面是 nginx。当 Sinatra 应用程序出错(返回 500)时,我想提供一个静态页面,而不是默认的“内部服务器错误”。我有以下 nginx 配置:

server {
  listen 80 default;
  server_name *.example.com;
  root /home/deploy/www-frontend/current/public;

  location / {
    proxy_pass_header Server;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    proxy_connect_timeout 5;
    proxy_read_timeout 240;
    proxy_pass http://127.0.0.1:4701/;
  }

  error_page 500 502 503 504 /50x.html;
}

error_page 指令在那里,我将 sudo 设置为 www-data (Ubuntu) 并验证我可以cat使用该文件,因此这不是权限问题。使用上面的配置文件,service nginx reload我收到的错误页面仍然是相同的“内部服务器错误”。

我的错误是什么?

4

4 回答 4

102

error_page处理 nginx 生成的错误。默认情况下,无论 http 状态码如何,nginx 都会返回代理服务器返回的任何内容。

您正在寻找的是proxy_intercept_errors

该指令决定 nginx 是否会拦截 HTTP 状态代码为 400 或更高的响应。

默认情况下,所有响应都将从代理服务器按原样发送。

如果您将其设置为 on,则 nginx 将拦截由 error_page 指令显式处理的状态代码。状态码与 error_page 指令不匹配的响应将从代理服务器按原样发送。

于 2012-01-03T16:48:12.110 回答
22

您可以为该位置设置 proxy_intercept_errors

location /some/location {
    proxy_pass_header Server;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    proxy_connect_timeout 5;
    proxy_read_timeout 240;
    proxy_pass http://127.0.0.1:4701/;
    proxy_intercept_errors on; # see http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors

    error_page 400 500 404 ... other statuses ... =200 /your/path/for/custom/errors;
}

你可以设置你需要的200个其他状态

于 2012-12-24T17:58:18.523 回答
6

使用 FastCGI 作为上游的人需要打开此参数

fastcgi_intercept_errors on;

对于我的 PHP 应用程序,我在上游配置块中使用它

 location ~ .php$ { ## Execute PHP scripts
    fastcgi_pass   php-upstream; 
    fastcgi_intercept_errors on;
    error_page 500 /500.html;
 }
于 2017-11-22T04:40:32.337 回答
0

正如斯蒂芬在这个回复中提到的那样,使用proxy_intercept_errors on;可以工作。虽然在我的情况下,正如在这个答案中看到的那样,使用uwsgi_intercept_errors on;成功了......

于 2017-02-13T22:29:32.647 回答