You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx文件上传无限加载与WebSocket协议切换错误排查

解决Nginx反向代理下文件上传无限加载与WebSocket切换协议错误

问题背景

上传文件时页面无限加载,但文件实际已上传成功;为了让Nginx优先处理静态文件添加try_files $uri @proxy后,WebSocket出现101 Switching Protocol错误。以下是原有配置:

原有/etc/nginx/nginx.conf配置

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

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

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;

        client_max_body_size 128M;
        proxy_max_temp_file_size 0;
        proxy_buffering off;
        server_names_hash_bucket_size 256;
}

原有/etc/nginx/sites-available/default配置

server {
    server_name zizzu.com;
    listen 80;

    # We miss all the declarations to make tls happens
    # But they should be somewhere here

    root /home/zizzu/Zizzu-API/Public/;

    # Serve all public/static files via nginx and then fallback to Vapor for the rest
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    client_max_body_size 128M;

    # Proxy configuration for binding to Vapor port
    location @proxy {
        proxy_pass http://127.0.0.1:8080;
        proxy_pass_header Server;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass_header Server;
        proxy_connect_timeout 3s;
        proxy_read_timeout 10s;
    }
}

修改location /后触发WebSocket错误的配置片段:

...
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        try_files $uri @proxy;
    }
...

解决方案

1. 调整/etc/nginx/nginx.conf

在http块中添加WebSocket连接头映射,并延长全局代理超时时间:

http {
    # ... 保留原有所有配置 ...

    # 处理WebSocket的Connection头,兼容非WebSocket请求
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    # 延长代理读取超时,适配大文件上传
    proxy_read_timeout 300s;
}

2. 修改/etc/nginx/sites-available/default

拆分静态文件、普通请求和WebSocket请求的代理规则,避免冲突:

server {
    server_name zizzu.com;
    listen 80;

    root /home/zizzu/Zizzu-API/Public/;
    client_max_body_size 128M;

    # 优先处理静态文件,找不到再转发到后端服务
    location / {
        try_files $uri @proxy;
    }

    # 普通API请求的代理配置
    location @proxy {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 3s;
        proxy_read_timeout 300s; # 继承全局超时,确保大文件上传完成
    }

    # 单独配置WebSocket路由(请根据实际WebSocket路径修改/ws)
    location /ws {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 86400s; # 保持WebSocket长连接需要的超时时间
    }
}

关键修改说明

  • 文件上传无限加载:原配置中proxy_read_timeout仅10秒,Nginx会在大文件上传完成前主动断开连接,前端因收不到响应进入无限加载状态,延长超时时间即可解决。
  • WebSocket 101错误:之前将WebSocket的协议升级头全局应用到所有请求,加上try_files后静态文件请求也被带上Upgrade头,导致协议切换逻辑混乱。单独为WebSocket路径配置升级规则,并用$connection_upgrade变量替代固定值,确保只有真实的WebSocket请求触发协议升级。

内容的提问来源于stack exchange,提问作者Artemiy Ziuzin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 16:34:50