IE11下异步POST请求首次失败、二次正常的技术问题求助
解决IE11下AJAX轮询首次获取历史数据的问题
看起来你在IE11里遇到了AJAX轮询的缓存和执行时机问题,我帮你梳理下问题原因和修复方案:
核心问题分析
setTimeout调用错误:你当前写的setTimeout(ajax_update2(), 50000)会立即执行ajax_update2函数,而不是延迟50秒执行,这会导致轮询在后端线程还没生成数据时就发起请求,拿到旧数据。- IE11的AJAX缓存机制:IE11会对AJAX请求(甚至POST请求)进行缓存,第一次请求的旧数据会被缓存,导致后续请求直接读取缓存内容。
async:false的副作用:同步AJAX会阻塞浏览器主线程,不仅影响用户体验,还可能打乱后续请求的执行顺序,导致数据更新不及时。
修复方案和代码调整
1. 修复setTimeout调用方式
把带括号的函数调用改成函数引用,确保延迟执行:
- 错误写法:
setTimeout(ajax_update2(), 50000);→ 正确写法:setTimeout(ajax_update2, 50000); - 错误写法:
setTimeout("ajax_update2()",5000);→ 正确写法:setTimeout(ajax_update2, 5000);
2. 禁用IE11的AJAX缓存
在ajax_update2的请求中添加防缓存配置,两种方式任选其一:
- 添加随机参数到请求URL或数据中,强制IE每次发送新请求
- 设置请求头禁止缓存
3. 移除async:false,改用异步请求
同步请求会阻塞浏览器,改用异步请求后在成功回调中启动轮询,更符合前端最佳实践。
调整后的完整代码
function runMon2() { $("#btnStop").show(); $("#btnStart").hide(); $("#msgz").html(""); $.ajax({ type: "POST", url: "stage2.aspx/s3_monte_carlo_run_thread", // 用JSON.stringify安全构建请求数据,避免字符串拼接出错 data: JSON.stringify({ id: "<%= id%>", no_cycles: $("#cycles").val(), covSmys: $("#covSmys").val(), covT: $("#covT").val(), covL: $("#covL").val(), covD: $("#covD").val(), D: "<%= D%>", L: "<%= L%>", T: "<%= T%>", Pa: "<%= Pa%>", UTS: "<%= UTS%>", SMYS: "<%= SMYS%>", assess_type: $("#assess_type").val(), year: "<%=year%>" }), dataType: 'json', // 移除async:false,改用异步请求 contentType: "application/json; charset=utf-8", success: function (data) { successmessage = 'RunMon2 Successfully enter data'; $("#progressbar").show(); $("#msgz").show(); // 修复setTimeout写法,延迟启动轮询 setTimeout(ajax_update2, 5000); // 可根据后端处理速度调整延迟时间 }, // jQuery的错误回调是error,不是fail error: function (data) { successmessage = 'RunMon2 Operation Failed'; console.log(successmessage); }, }); } function ajax_update2() { $("#btnStop").show(); $("#btnStart").hide(); console.log("ajax_update2"); $.ajax({ type: "POST", // 添加随机参数防止IE缓存 url: "stage2.aspx/s3_monte_carlo_refresh?_t=" + new Date().getTime(), data: JSON.stringify({ id: "<%= id%>" }), dataType: 'json', contentType: "application/json; charset=utf-8", // 额外添加禁止缓存的请求头,双重保障 headers: { "Cache-Control": "no-cache", "Pragma": "no-cache", "Expires": "0" } }) .done(function (data) { var responseData = $.trim(data.d); console.log(responseData); if (responseData == "") { $("#msgz").hide(); $("#btnStart").show(); $("#btnStop").hide(); console.log("data empty"); return; } var dd = responseData.split("!"); if (parseFloat(dd[0]) == 100) { $("#progressbar").hide(); $("#msgz").html(dd[1]); $("#btnStop").hide(); $("#btnStart").show(); console.log("data complete"); return; } $("#progressbar").progressbar("option", "value", parseFloat(dd[0])); $("#msgz").html(dd[1]); // 修复setTimeout写法,继续轮询 setTimeout(ajax_update2, 5000); successmessage = 'Successfully enter ajax_update2'; console.log(successmessage); }) // 添加请求失败的重试逻辑,避免轮询中断 .fail(function() { setTimeout(ajax_update2, 5000); console.log("ajax_update2 request failed, retrying..."); }); }
额外检查点
- 确认后端
s3_monte_carlo_refresh接口是否能实时返回最新数据:可以在后端添加日志,查看每次请求时对应id的数据状态,确保线程启动后数据能及时更新。 - 如果后端线程启动后需要一定时间生成数据,可以适当延长
runMon2中启动轮询的延迟时间,避免首次请求时数据还未生成。
内容的提问来源于stack exchange,提问作者ainulm
相关产品推荐
相关产品推荐

