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