WebFlux控制器无法向ServerHttpResponse写入内容求助
问题分析与修复步骤
你的代码在m3u8分支下无法返回内容,核心原因有两个:
1. 未同步响应状态码
default分支直接转发clientResponse的body时,WebFlux会自动同步原响应的状态码,但m3u8分支未做该操作,导致浏览器无法正确识别响应状态。
2. Content-Length头部不匹配
原响应的Content-Length对应原始m3u8内容的长度,而你处理后的内容长度已改变,若保留该头部,浏览器会按旧长度等待数据,最终因数据不匹配判定加载失败。
修复后的核心修改点
步骤1:同步响应状态码
在复制响应头和Cookie后,添加状态码同步逻辑:
serverHttpResponse.setStatusCode(clientResponse.statusCode());
步骤2:移除旧的Content-Length头部
处理后的内容长度变化,需移除原Content-Length,让WebFlux自动使用分块编码(Transfer-Encoding: chunked)传输:
serverHttpResponse.getHeaders().remove(HttpHeaders.CONTENT_LENGTH);
步骤3:优化内容写入逻辑
将transform替换为更直观的flatMap,确保数据流被正确订阅:
完整修改后的代码片段:
.exchangeToMono(clientResponse -> { serverHttpResponse.setStatusCode(clientResponse.statusCode()); // 新增:同步原响应状态码 serverHttpResponse.getCookies().putAll(clientResponse.cookies()); serverHttpResponse.getHeaders().putAll(clientResponse.headers().asHttpHeaders()); serverHttpResponse.getHeaders().remove(HttpHeaders.CONTENT_LENGTH); // 新增:移除不匹配的长度头部 Mono<String> content; switch (mode) { case "m3u8": content = clientResponse.bodyToMono(String.class) .map(contentL -> playlistProvider.print( playlistProvider.proxify(uri, proxyService, playlistProvider.parse(contentL)))); break; default: return serverHttpResponse.writeWith(clientResponse.bodyToFlux(DataBuffer.class)); } return content .map(contentL -> serverHttpResponse.bufferFactory().wrap(contentL.getBytes())) .flatMap(dataBuffer -> serverHttpResponse.writeWith(Mono.just(dataBuffer))); })
额外验证点
- 确认
playlistProvider.proxify和print方法返回的是有效的m3u8格式,避免因内容格式错误导致浏览器无法解析。 - 开启WebFlux DEBUG级日志,检查数据流处理过程是否有异常。
内容的提问来源于stack exchange,提问作者sjngm
相关产品推荐
相关产品推荐

