网页多次重定向问题

问题描述

访问链路:Client ---https(443)---> CLB ---http(18088)---> Nginx

当请求访问的是目录,而又没有主动在URL带/时,Nginx会加上/并返回让浏览器重新请求一次,这时候重定向的Location可能与预期不符。

具体现象为,当访问 test.example.com/haha 时,先发生一次 301 Moved Permanently ,接着发生一次 307 Temporary Redirect地址变更为 test.example.com:18088/haha/ ,最后再用 test.example.com:18088/haha/ 访问。

根因分析

当 CLB 终止 HTTPS、并以 HTTP 转发到后端 Nginx(如 18088 端口)时,如果 Nginx 触发了由其生成的重定向,默认可能会按当前请求在 Nginx 看来 的协议、主机、端口与目标 URI 组装出一个绝对的 Location 返回给客户端。因此在该链路下,Location 里可能会出现 http 以及后端监听端口,而不是客户端最初访问时使用的 HTTPS 信息。这一点可以从日志也可以确认

arduino 复制代码
100.122.21.71 - test.example.com "GET /haha HTTP/1.1" 301 "https" "http" "http://test.example.com:18088/haha/"

日志字段内容参考

dart 复制代码
log_format debug  '$remote_addr - $host "$request" $status '
                  '"$http_x_forwarded_proto" "$scheme" "$sent_http_location"';

该行为是由 absolute_redirect 控制,并默认设置为on,若设置为 off ,当重定向发生时只会返回相对Location

问题的根因在于 Nginx 发生重定向时默认返回的是绝对 Location,其中会包含协议、主机、端口和 URI。由于当前链路中 CLB 到后端 Nginx 使用的是 HTTP,且 Nginx 监听的是自定义端口 18088,所以 Nginx 在构造重定向地址时,可能会把内部感知到的 http18088 一并返回给客户端,进而导致客户端发生异常跳转。

因此,可以考虑关闭 absolute_redirect 。这样当重定向发生时,Nginx 返回的将是相对路径,而不是包含协议、域名和端口的绝对路径,从而避免将后端内部链路信息暴露给客户端,也能规避这类跳转异常问题。

如果问题只是在重定向时把 Nginx 的监听端口带给了客户端,可以考虑调整 port_in_redirect。该参数默认是 on,用于控制 Nginx 发出的绝对重定向 中是否带端口。server_name_in_redirect 则用于控制重定向时主机名的选择。

相关推荐
乘云数字DATABUFF2 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
荣--4 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森4 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜5 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB6 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode7 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220708 天前
如何搭建本地yum源(上)
运维
ping某9 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树8811 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠11 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql