如何从Webflux的ServerHttpRequest中稳定获取浏览器端请求域名?
如何从ServerHttpRequest稳定获取发起请求的网站域名
你遇到的问题本质是浏览器不会在所有场景下都携带Origin或Referer头,而getRemoteAddress()获取的是客户端IP,和请求来源域名完全无关。要稳定获取来源域名,需要分场景处理,并做好兜底逻辑:
核心原因分析
Origin头:仅在跨域请求时由浏览器强制发送,同源请求不会携带;格式为协议://域名:端口(端口非默认时显示)。Referer头:仅在从其他页面跳转/发起请求时发送,直接输入URL访问、浏览器隐私设置禁用、HTTPS跳转HTTP等场景下会为空或被截断;格式为完整请求URL。- 直接访问场景:用户在地址栏直接输入你的服务域名,此时既无Origin也无Referer,不存在“发起请求的网站域名”。
稳定获取的实现步骤
- 优先尝试从
Origin头解析,因为跨域场景下Origin的存在更可靠; - Origin不存在时,尝试从
Referer头解析,注意处理非法URL格式; - 两者都为空时,判断为直接访问,可返回当前服务的域名(或根据业务需求返回空/提示)。
代码示例
ServerHttpRequest request = ...; // 你的请求对象 // 1. 从Origin头提取域名 String origin = request.getHeaders().getOrigin(); if (origin != null) { try { UriComponents originUri = UriComponentsBuilder.fromUriString(origin).build(); String domain = originUri.getHost(); // 若需要包含非默认端口,可改为:domain + (originUri.getPort() != -1 ? ":" + originUri.getPort() : "") return domain; } catch (IllegalArgumentException e) { // 处理非法Origin格式,忽略并继续尝试 } } // 2. 从Referer头提取域名 List<String> refererList = request.getHeaders().getOrEmpty("referer"); if (!refererList.isEmpty()) { try { UriComponents refererUri = UriComponentsBuilder.fromUriString(refererList.get(0)).build(); String domain = refererUri.getHost(); // 同理可选择添加端口 return domain; } catch (IllegalArgumentException e) { // 处理非法Referer格式,忽略 } } // 3. 兜底:直接访问场景,返回当前服务的域名(或根据业务需求返回null) UriComponents currentUri = UriComponentsBuilder.fromHttpRequest(request).build(); return currentUri.getHost();
注意事项
- 浏览器隐私模式、广告拦截插件可能会阻止Referer发送,这种场景下无法获取跳转来源域名;
- HTTPS站点跳转到HTTP站点时,浏览器会自动移除Referer,避免泄露HTTPS地址;
- 同源请求下,只能依赖Referer,但Referer为空的情况无法避免,需提前和业务方明确这种场景的处理逻辑。
内容的提问来源于stack exchange,提问作者user3648235
相关产品推荐
相关产品推荐

