向Keycloak发起的AJAX令牌获取请求在IE浏览器中运行失效问题
问题根因
服务端抛出java.io.IOException: Underlying input stream returned zero bytes错误的核心原因是:IE浏览器发送POST请求时未携带请求体中的表单参数,Keycloak解析表单时读取不到任何内容直接抛出异常。这个问题完全由你当前AJAX配置中的几个IE不兼容项导致,和Keycloak服务端本身逻辑无关:
- 手动添加了
Accept-Encoding: gzip, deflate, br请求头:IE全版本均不支持br(Brotli)压缩算法,且跨域场景下IE禁止JavaScript手动修改Accept-Encoding这类浏览器控制的请求头,强行设置会触发浏览器底层的请求组装异常,直接导致请求体丢失。 - 设置了
processData: false:当传入的data是预拼接的urlencoded字符串时,该配置在现代浏览器中可正常运行,但IE在跨域POST场景下,搭配手动指定的Content-Type头时,processData: false会让浏览器跳过请求体的编码校验步骤,最终发送空的请求载荷。 - 手动设置了
Connection: keep-alive请求头:和Accept-Encoding类似,连接管理类请求头属于浏览器控制范畴,IE跨域场景下不允许JS修改该头,强行设置会触发请求异常。 - 你贴出的代码中
success回调缺少闭合的},属于语法笔误,运行时也会触发脚本错误,需要一并修复。
修复方案
直接调整AJAX配置即可兼容所有浏览器,修正后的代码如下:
$.ajax({ method: "POST", url: "https://url/to/server", headers: { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' // 移除Accept-Encoding、Connection等浏览器自动控制的请求头,不要手动设置 }, cache: false, crossDomain: true, processData: true, // 开启processData,让jQuery自动处理参数编码 data: { username: 'test', password: 'test' // 其余所有表单参数以key-value形式直接写在这里,不要手动拼接字符串 }, dataType: 'json', success: function (resp) { console.log(resp.access_token); }, // 补全success回调的闭合括号 error: function (resp) { console.log(resp); } });
额外排查项
如果调整配置后问题仍存在,按以下顺序检查:
- 确认Keycloak对应客户端的
Web Origins配置,已经将你发起请求的站点源地址(包含协议、域名、端口)加入允许列表。IE对CORS的校验规则比现代浏览器更严格,源地址未加白会导致预检请求异常,最终发送空请求体。 - 在页面
<head>标签最前面添加<meta http-equiv="X-UA-Compatible" content="IE=edge">,强制IE使用当前版本最高内核渲染,避免兼容模式下XMLHttpRequest对象的已知跨域BUG。 - 如果你的站点和Keycloak服务是同域部署但端口不同,在IE下也会被判定为跨域,不要通过修改IE安全设置的方式关闭跨域校验,会导致更多请求异常。
内容的提问来源于stack exchange,提问作者devdev
相关产品推荐
相关产品推荐

