Express和nginx出现net::ERR_CONTENT_LENGTH_MISMATCH错误

13

我正在开发一个基于Express的网站,并通过nginx代理进行访问。有时,当我在浏览器中加载页面时,会出现以下情况:

GET http://myapp.local/css/bootstrap.css net::ERR_CONTENT_LENGTH_MISMATCH

输入图像描述

如果我刷新页面,它通常会消失。但是如果一遍又一遍地刷新,它就会再次出现。

问题出在哪里?有什么方法可以缩小问题范围吗?这是我的此服务器上的nginx配置:

server {
  listen 80;
  server_name www.myapp.local;
  rewrite ^(.*) http://myapp.local$1 permanent;
}

server {
  listen 80;
  server_name myapp.local;

  access_log /vagrant/nginx/logs/myapp.local/access.log;
  error_log /vagrant/nginx/logs/myapp.local/error.log;

  location / {
    proxy_pass http://localhost:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}

这肯定是与nginx代理有关的问题。因为如果我只使用IP地址和Node端口访问网站:http://10.10.10.10:8080,那么我永远不会遇到错误。但是如果我使用代理后的虚拟主机访问:http://myapp.local,我最终会遇到错误(也许每10次中有1次)。


首先,我会在nginx日志(/var/log/nginx/*)中使用grep命令查找所有涉及bootstrap.css的请求。此外,可以参考这个serverfault答案,使用return关键字来实现更好的rewrite风格(该答案是关于https的,但同样适用于从url中删除www.)。 - grochmal
4个回答

14
这是一个代理缓冲的问题。启用缓冲时,nginx尽快从被代理服务器接收响应,并将其保存到由proxy_buffer_sizeproxy_buffers指令设置的缓冲区中。如果整个响应不适合内存,则可以将部分响应保存到磁盘上的临时文件中。写入临时文件由proxy_max_temp_file_sizeproxy_temp_file_write_size指令控制。
禁用缓冲时,响应会同步传递给客户端,就像它接收到的那样。nginx不会尝试从被代理服务器读取整个响应。nginx从服务器一次接收的数据的最大大小由proxy_buffer_size指令设置。
因此,您可以简单地禁用代理缓冲来解决此问题:
proxy_buffering  off;

还要注意,nginx只是试图在磁盘上写入临时文件,如果磁盘已满,则会出现相同的错误。因此,在禁用proxy_buffering之前,请检查您的磁盘使用情况。


在生产环境中,proxy_buffering应该开启还是关闭?如果环境中的本地文件发生更改,如何“清除代理缓存”或称之为什么?我是否需要将设置关闭,重新启动nginx,然后再将其更改回来并重新启动它? - Jake Wilson
2
添加proxy_buffering off;解决了我的问题。 - Miguel Mota
请注意,nginx只是试图在磁盘上写入临时文件,如果磁盘已满,则会收到相同的错误。因此,在禁用“proxy_buffering”之前,请检查磁盘使用情况。 - Arash Milani
2
警告:禁用代理缓冲实际上是相当危险的,除非您确切知道自己在做什么,否则不建议这样做。通常,反向代理和后端应用程序服务器位于非常快速的局域网上。但客户端连接质量会有所不同,有时会出现停顿。如果代理的客户端连接对代理的上游连接造成背压(大型资产或HTTP/2),它可能会将应用程序服务器托管,因为它被迫以客户端较慢的速度排空响应的尾部。来源:https://www.maxcdn.com/blog/nginx-application-performance-optimization/ - Mouneer

11
net::ERR_CONTENT_LENGTH_MISMATCH是一个缓存问题。如果满足某些条件(在您的情况下是$http_upgrade),您告诉Nginx绕过缓存。
您应该在某个配置文件中为nginx指定缓存位置。一个快速的解决方法是删除此文件夹的内容,重新启动nginx,然后再次尝试访问网站。另一个以缓存为代价的快速解决方法是删除proxy_cache_bypass $http_upgrade;这行。
如果您提供有关缓存设置的更多详细信息,也许可以改进此答案。

8
谢谢你的分享。我也发现添加“proxy_buffering off”似乎也有效。谢谢。 - Jake Wilson
3
警告:禁用代理缓冲实际上是相当危险的,除非你确切知道自己在做什么,否则不建议这样操作。通常情况下,反向代理和后端应用服务器被放置在一个非常快速的局域网中。但客户端连接质量会有所不同,有时会出现停滞。如果代理的客户端连接对代理的上游连接造成背压(大型资源或HTTP/2),它可以将一个应用服务器挟持,强制以客户端较慢的速度耗尽响应的尾部。来源:https://www.maxcdn.com/blog/nginx-application-performance-optimization/ - Mouneer
@JakeWilson 你救了我一天。我遇到了同样的问题,最终你的答案起作用了。谢谢你啊! - Raj Kumar N

0
当我尝试上述解决方案时,它并没有解决问题。我也更改了写入位置的权限,但仍然无效。后来我意识到我在那里做错了什么。在存储文件的位置上,我有类似于

"/storage" + fileName + ".csv"

的东西。我在Windows环境下测试时效果很好。但是后来当我们将应用程序移动到Linux环境时,它停止工作了。所以后来我不得不将其更改为

"./storage" + fileName + ".csv"

然后它就正常工作了。


0

如果有人遇到了这个问题,而且代理缓冲解决方案对他们无效。我首先想建议在API调用中添加“X-Accel-Buffering: no”,而不是更改代理缓冲:

通过在“X-Accel-Buffering”响应头字段中传递“yes”或“no”也可以启用或禁用缓冲。

最后,问题也可能与权限有关。如果您最近更改了Nginx用户,则新用户可能无法访问Nginx写入的代理临时文件夹。您可能将此文件夹放在“/usr/local/var/run/nginx”下。您必须更改此文件夹的权限以匹配Nginx的用户和组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接