如何从Webflux的ServerHttpRequest中稳定获取请求方网站域名?
如何从ServerHttpRequest稳定获取请求方网站域名
为什么现有方法不稳定
getRemoteAddress().getHostName():依赖DNS反向解析客户端IP,大概率返回用户IP而非网站域名,且解析可能失败。Origin/Referer头:由浏览器主动发送,但存在多种缺失场景:- 直接在地址栏输入URL、刷新页面时,
Referer会缺失; - 浏览器隐私设置禁用
Referer发送; - 跨域简单请求(如GET)可能不携带
Origin头。
- 直接在地址栏输入URL、刷新页面时,
稳定获取的可行方案
1. 前端主动携带自定义请求头(可控场景首选)
如果请求来自你开发的前端应用,可在请求拦截器中主动添加自定义头(如X-Request-Domain),后端直接读取即可稳定获取域名。
后端读取代码:
String requestDomain = requests.getHeaders().getFirst("X-Request-Domain");
注意:跨域请求需在后端CORS配置中允许该自定义头,避免浏览器拦截。
2. 利用反向代理转发头(部署在代理后时使用)
若服务部署在Nginx、Apache等反向代理之后,可配置代理添加X-Forwarded-Host头,将用户实际访问的域名传递给后端。
Nginx配置示例:
proxy_set_header X-Forwarded-Host $host;
后端读取代码:
String requestDomain = requests.getHeaders().getFirst("X-Forwarded-Host");
⚠️ 注意:需在后端配置中信任代理的转发头,避免恶意请求伪造该头引发安全问题。
3. 多方案兜底兼容(通用场景)
对于无法控制前端或代理的场景,可结合多种方式按优先级读取,最大化获取成功率:
String requestDomain = null; // 1. 优先读取自定义头 requestDomain = requests.getHeaders().getFirst("X-Request-Domain"); // 2. 读取Origin头并处理域名部分 if (requestDomain == null) { List<String> origins = requests.getHeaders().getOrEmpty("origin"); if (!origins.isEmpty()) { String origin = origins.get(0); // 去除协议前缀(如https://),只保留域名 requestDomain = origin.replaceAll("^https?://", ""); } } // 3. 解析Referer头提取域名 if (requestDomain == null) { List<String> referers = requests.getHeaders().getOrEmpty("referer"); if (!referers.isEmpty()) { try { URI refererUri = new URI(referers.get(0)); requestDomain = refererUri.getHost(); } catch (URISyntaxException e) { // 解析失败时忽略,继续尝试兜底方案 } } } // 4. 兜底:使用当前请求的服务域名(适合同域请求场景) if (requestDomain == null) { requestDomain = requests.getURI().getHost(); }
核心说明
不存在绝对100%稳定的获取方式,因为浏览器是否发送Origin/Referer受安全规则、用户隐私设置影响。需结合部署场景(是否有代理)、请求来源(是否可控前端)选择合适方案,才能最大化成功率。
内容的提问来源于stack exchange,提问作者user3648235
相关产品推荐
相关产品推荐

