Nginx 代理 OnlyOffice 时 URL 端口丢失问题

引言

在使用 Nginx 作为反向代理服务 OnlyOffice 时,发现原本应为https://ip:port/cache/...的请求,在经过 Nginx 代理后,变成了https://ip/cache/...

问题描述

当 Nginx 配置如下代理 OnlyOffice 请求时:

location ~* /(8.3.0-|web-apps|cache/files) {
    # OnlyOffice 容器的地址和端口
    proxy_pass http://192.168.1.186:8050;

    # 设置必要的头信息
    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_set_header X-Forwarded-Proto $scheme;

    # WebSocket 支持(OnlyOffice 协作编辑依赖)
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    proxy_set_header X-Frame-Options "SAMEORIGIN";

    # 超时设置
    proxy_connect_timeout 7d;
    proxy_send_timeout 7d;
    proxy_read_timeout 7d;
    send_timeout 7d;

    # 缓冲设置
    proxy_buffering off;
}

观察到正常应该对https://ip:port/cache/files/data/3564657e6e/Editor.bin/Editor.bin?...的请求,在实际访问时,端口号被移除,变为https://ip/cache/files/data/3564657e6e/Editor.bin/Editor.bin?...。导致 OnlyOffice 编辑器无法下载文件并回显。

问题分析

此问题的根本原因在于 OnlyOffice 服务在生成重定向或资源链接时,依赖于请求头中的Host和协议信息来构造返回的 URL。尽管 Nginx 配置中包含了proxy_set_header Host $host;,但$host变量在某些情况下并不包含端口号,从而导致后端服务生成的 URL 缺少端口。

解决方案:强制在Host头中保留端口号

为解决此问题,需要确保传递给 OnlyOffice 后端的Host头中始终包含端口号,即使该端口是标准端口(如 443)。这可以通过修改 Nginx 的proxy_set_header Host指令来实现。

修改方式

将 Nginx 配置中的proxy_set_header Host $host; 修改为proxy_set_header Host $host:$server_port;

location ~* /(8.3.0-|web-apps|Editor.bin) {
    proxy_pass http://192.168.1.186:8050;

    # 关键修改:强制设置 Host 头,包含当前服务器监听的端口号
    proxy_set_header Host $host:$server_port;
    # 如果希望固定某个特定端口(例如 8443),也可以这样写:
    # proxy_set_header Host $host:8443;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # WebSocket 支持(OnlyOffice 协作编辑依赖)
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    proxy_set_header X-Frame-Options "SAMEORIGIN"; # 允许嵌套

    # 超时设置
    proxy_connect_timeout 7d;
    proxy_send_timeout 7d;
    proxy_read_timeout 7d;
    send_timeout 7d;

    # 缓冲设置
    proxy_buffering off;
}

关键指令解释

下表详细解释了 Nginx 中与Host头相关的几个变量和指令:

指令/变量 说明
$host 通常是客户端请求头中Host字段的值。如果客户端请求的是标准端口(如 80 或 443),浏览器通常会省略端口,此时$host不包含端口
$http_host 等同于$host。在未设置Host请求头时,此变量可能为空。
$server_port Nginx 服务器当前监听的端口号。例如,如果 Nginx 监听 8443 端口,则$server_port的值为8443
proxy_set_header Host $host:$server_port; 推荐的解决方案。此指令强制将Host请求头设置为客户端请求的域名(或 IP)与 Nginx 监听端口的组合。这样,即使客户端请求的Host头不带端口,后端 OnlyOffice 服务也能收到完整的Host:Port信息,从而生成正确的带端口的 URL。

总结

OnlyOffice 在 Nginx 代理下出现 URL 端口丢失的问题,其核心在于 Nginx 的$host变量在某些情况下不包含端口信息,导致 OnlyOffice 后端生成了错误的资源链接。通过将proxy_set_header Host $host:$server_port; 添加到 Nginx 配置中,可以强制将完整的Host:Port信息传递给 OnlyOffice 后端,从而解决此问题。

参考:Qwen

posted @ 2025-08-30 17:17  Higurashi-kagome  阅读(7)  评论(0)    收藏  举报