我有一个 Rails 应用程序,在使用大 cookie 时遇到问题。例如,在浏览器中的 https://api.my-app.com/v1 (API 端点)和 https://app.my-app.com (主应用程序),它最初加载美好的。但是,当我手动添加 cookie 时,一旦 cookie 总大小超过 8KB,应用程序就会停止工作,显示 400 Bad Request。发生的事情是这样的:
如果我在浏览器中访问该 URL(以隐身模式),它会正确加载。 然后我开始手动添加 cookie,直到总大小达到 8KB。到目前为止,该应用程序仍然运行良好。 一旦 cookie 总大小超过 8KB,我会得到一个
400 Bad Request, Request Header Or Cookie Too Large, nginx
错误。
除了我添加的 cookie 之外,浏览器中没有其他 cookie,并且我通过 DevTools 验证了请求中仅发送我的自定义 cookie。
但是,如果我从网络选项卡将失败的请求复制为 cURL 命令并在终端中运行它或通过 Postman 发送它(即使 cookie 大小高达 10-12KB),它也可以完美运行,没有任何错误。
在我的 Kubernetes 入口配置中,我设置了以下注释来处理更大的标头大小:
nginx.ingress.kubernetes.io/server-snippet: |
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
这是复制请求的 cURL 命令。我在请求中使用了三个 cookie:
我从终端和邮递员都收到了没有错误的响应。但是,在浏览器中,此请求会返回 400 错误。如果我删除large_cookie3,浏览器也会收到良好的响应。
curl 'https://api.my-app.com/v1' \
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
-H 'accept-language: en-US,en;q=0.9' \
-H 'cache-control: no-cache' \
-H 'cookie: large_cookie1=aaa...; large_cookie2=bbb...; large_cookie3=ccc..' \
-H 'pragma: no-cache' \
-H 'priority: u=0, i' \
-H 'sec-ch-ua: "Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "macOS"' \
-H 'sec-fetch-dest: document' \
-H 'sec-fetch-mode: navigate' \
-H 'sec-fetch-site: none' \
-H 'sec-fetch-user: ?1' \
-H 'upgrade-insecure-requests: 1' \
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36'
这个问题似乎只影响从浏览器发出的请求,我不确定为什么它在终端或 Postman 中会有不同的行为。
可能导致这种差异的原因是什么,如何解决它以便浏览器请求中也接受大 cookie?
HTTP 400 Bad Request 客户端错误响应状态代码表示服务器不会处理该请求,因为服务器认为是客户端错误。
任何设置的大小大于限制的 cookie 都会被忽略(并且不会设置)。
大多数浏览器对 Cookie 的大小都有限制,请检查浏览器 Cookie 限制以了解一些常见的浏览器。当 cookie 的总大小超过此限制时,浏览器可能会拒绝该请求。例如,Chrome 浏览器每个域的 Cookie 计数限制为 180 个,Cookie 总大小为 4096。
错误消息请求标头或 Cookie 太大。您的标头之一非常大,nginx 拒绝了它。您使用的是 nginx 服务器,请尝试增加缓冲区值并将其设置为 large_client_header_buffers 4 32k。
检查您的 Kubernetes 入口注释,确保它们正确应用,并且入口控制器已正确配置为处理大型标头。
请参阅 Docdevs 的此文档了解更多信息
注:
为了支持大多数浏览器,每个域的 cookie 不应超过 60 个,并且 cookie 总大小(所有 cookie)应小于或等于 4093 字节。