首页 > 解决方案 > 对于请求标头或 Cookie 太大,如何让 nginx 返回 431 而不是 400?

问题描述

我有一个默认的 nginx 配置(我没有明确返回400任何场景):

http {
    ...
    
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    ...

    include /etc/nginx/conf.d/*.conf;
}

它返回

<html>
<head><title>400 Request Header Or Cookie Too Large</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>Request Header Or Cookie Too Large</center>
<hr><center>nginx</center>
</body>
</html>
* Closing connection 0

没关系。

但是我想更改 nginx 配置以返回431而不是返回400那种错误,最简单的方法是什么?

我尝试查看以下问题:

但他们更多的是关于修复错误而不是返回不同的状态代码。

另一种解决方案可能是突破限制:

server {
    # ...
    large_client_header_buffers 4 32k;
    # ...
}

通过关注https://stackoverflow.com/a/19285146/17109505

我还发现了一个在块下执行的配置:map $status $status_text {http

map $status $status_text {
...
        431 'Request Header Fields Too Large';
...
    }

它能够解决这个问题吗?

标签: nginxreverse-proxynginx-reverse-proxy

解决方案


除了真实服务器配置之外,您没有显示任何内容,include /etc/nginx/conf.d/*.conf;所以我只能猜测它真正包含的内容。您可以尝试通过error_page以下方式使用指令:

error_page 400 =431 /431.html;

创建以下 HTML 文件并将其放在某处(例如,/usr/share/nginx/html文件夹)(同样,您可以在该文件中放置任何内容,这只是一个示例):

<html>
<head><title>431 Request Header Or Cookie Too Large</title></head>
<body>
<center><h1>431 Bad Request</h1></center>
<center>Request Header Or Cookie Too Large</center>
<hr><center>nginx</center>
</body>
</html>

此自定义错误页面不应包含任何外部资源(即脚本、样式、图像等)引用(但是您可以使用任何内联样式、脚本甚至 BASE64 编码的图像)。

现在在您的服务器块中使用以下位置:

location = /431.html {
    internal;
    root /usr/share/nginx/html;
}

我还发现了一个在块下执行的配置:map $status $status_text { ... }http

map $status $status_text {
    ...
    431 'Request Header Fields Too Large';
    ...
}

它能够解决这个问题吗?

多么有趣的解决方案!它使用内部 nginx 变量$status从响应状态代码中获取错误消息,然后通过服务器端包含在通用错误页面中使用这些$status$status_text变量。我第一次看到这样的技术,非常好的方法。但是,我不确定它是否对您的特定情况有用。如果您想使用类似的通用错误页面,则至少需要两个指令:error.htmlerror_page

error_page 400 =431 /error.html;        # change response status code from 400 to 431
error_page 401 402 403 ... /error.html; # left other response status codes unchanged

推荐阅读