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
浙公网安备 33010602011771号