IE11中含FormData的AngularJS请求在Struts2中部分失败问题排查
IE11中AngularJS FormData传递数组导致Struts2后端参数为null的问题分析
问题背景
你遇到的这个场景很典型:在AngularJS里用FormData传数据到Struts2后端时,Chrome和Firefox都能正常解析,但到了IE11,只要传递的是数组类型变量,后端的JsonInput参数就会变成null;但换成对象类型变量,或者直接传入预编码好的字符串,就完全正常。
可能的原因拆解
IE11对FormData的处理和现代浏览器存在不少兼容性差异,尤其是在复杂数据类型的序列化环节:
- 冗余的序列化嵌套导致格式异常:你原代码里用了
angular.toJson(encodeURIComponent(JSON.stringify(myVariable)))三层嵌套转换——其实JSON.stringify已经能把数组转成标准JSON字符串,angular.toJson和它功能高度重复,嵌套使用会在IE11中产生双重转义,生成的字符串格式超出了Struts2参数解析器的识别范围。 - IE11对FormData中数组类数据的编码逻辑特殊:现代浏览器会按标准处理FormData里的JSON字符串,但IE11可能会额外添加浏览器自身的编码规则,导致后端无法正确解码参数。
- Struts2解析器对IE11请求的容错性不足:IE11发送的请求头或表单数据格式和现代浏览器略有差异,Struts2默认的参数注入逻辑对这种差异的适配不够,尤其是针对数组类型的JSON参数。
针对性解决方案
方案1:简化JSON序列化逻辑
去掉冗余的angular.toJson,只保留必要的序列化和编码步骤,避免双重转义:
// 原冗余代码 formData.append("JsonInput", angular.toJson(encodeURIComponent(JSON.stringify(myVariable)))); // 修改后二选一即可 formData.append("JsonInput", encodeURIComponent(JSON.stringify(myVariable))); // 或者直接用angular.toJson(它已内置转义处理) formData.append("JsonInput", angular.toJson(myVariable));
方案2:手动模拟可靠的编码格式
如果方案1无效,可以手动复刻你测试成功的temp变量格式,确保前端生成的编码字符串完全符合后端预期:
var jsonStr = JSON.stringify(myVariable); var encodedStr = encodeURIComponent(jsonStr); formData.append("JsonInput", encodedStr);
方案3:后端手动解析参数
如果前端调整后还是有问题,可以在Struts2 Action里跳过自动注入,手动获取并解析参数:
HttpServletRequest request = ServletActionContext.getRequest(); String jsonInput = request.getParameter("JsonInput"); // 手动解码并解析为数组 jsonInput = URLDecoder.decode(jsonInput, "UTF-8"); ObjectMapper mapper = new ObjectMapper(); List<YourBean> dataList = mapper.readValue(jsonInput, new TypeReference<List<YourBean>>(){});
容易触发问题的变量类型/场景
在IE11+AngularJS+Struts2的组合下,以下情况大概率会踩坑:
- 包含对象的嵌套数组或多维数组:这类复杂结构的数组,IE11的序列化逻辑和现代浏览器差异最明显。
- 同时使用多种JSON序列化方法:比如
JSON.stringify和angular.toJson嵌套,导致双重转义生成异常格式。 - 未显式指定编码格式的字符串:IE11可能用非UTF-8编码处理FormData内容,后端解码时直接失败。
内容的提问来源于stack exchange,提问作者mtnp
相关产品推荐
相关产品推荐

