如何替换同步Ajax为同步Fetch?同步XMLHttpRequest告警解决求助
解决主线程同步XMLHttpRequest废弃告警,同时保留原有功能
嘿,我完全懂你的处境——虽然同步Ajax调用早就不被推荐,但对接的设备必须等用户操作后才返回响应,这确实让你没得选。不过别担心,我们可以把同步逻辑改成异步的,既能消除浏览器的废弃告警,又100%保留你原来的功能流程。
问题根源
你原来的代码用了async: false把Ajax变成同步,这会阻塞主线程,现在浏览器已经明确标记这种用法为废弃,所以会抛出告警。我们的核心目标是把同步的顺序逻辑改成异步的链式调用,确保先拿到设备响应,再发起第二个请求。
方案1:使用jQuery的回调链式调用
这是最兼容的写法,不管你用哪个版本的jQuery都能跑:
$(document).ready(function() { // 第一步:异步请求设备响应 $.ajax({ url: 'url', type: "GET" }).done(function(deviceResponse) { // 拿到设备响应后,立即发起第二个POST请求 $.post("https://example.com/doit.php", { response: deviceResponse, account: <?php echo $account ?>, dn: <?php echo $dn ?>, mode: <?php echo $dest ?> }).done(function(data) { // 和原来一样输出结果 document.write(data); }).fail(function() { // 新增错误处理:第二个请求失败时的提示 console.error('生成输出的请求失败了'); }); }).fail(function() { // 新增错误处理:获取设备响应失败时的提示 console.error('获取设备响应失败,请检查设备连接'); }); });
为什么这么改:
- 去掉了
async: false,让Ajax回归异步,不再阻塞主线程,自然消除告警。 - 用
.done()回调保证了执行顺序:只有第一个请求成功拿到设备响应后,才会触发第二个请求,和你原来的同步逻辑完全一致。 - 新增了
.fail()错误处理,比原来的同步代码更健壮——原来同步请求失败可能直接卡住页面,现在可以捕获错误并给出提示。
方案2:用async/await让代码更像同步写法(推荐)
如果你的项目用的是jQuery 3.0及以上版本,$.ajax会返回标准的Promise,这时候可以用async/await语法,让代码逻辑和原来的同步写法几乎一样,但本质是异步的:
$(document).ready(async function() { try { // 异步获取设备响应,await会等待请求完成再往下走 const deviceResponse = await $.ajax({ url: 'url', type: "GET" }); // 发起第二个请求,同样等待完成 const data = await $.post("https://example.com/doit.php", { response: deviceResponse, account: <?php echo $account ?>, dn: <?php echo $dn ?>, mode: <?php echo $dest ?> }); // 输出结果 document.write(data); } catch (error) { // 统一捕获所有请求的错误 console.error('请求过程中出错:', error); } });
为什么推荐这个方案:
- 代码逻辑和你原来的同步代码几乎一致,可读性更强,维护起来更方便。
- 同样是异步执行,不会阻塞主线程,消除告警。
- 用
try/catch统一处理所有错误,代码更简洁。
关于document.write的小提醒
你原来的代码用document.write输出结果,要注意:如果在$(document).ready()里调用它,会覆盖整个页面的内容——这和你原来的行为是一致的,但如果之后想避免覆盖页面,你可以把输出目标改成某个DOM元素,比如:
// 假设页面上有个<div id="output"></div> $('#output').html(data);
内容的提问来源于stack exchange,提问作者Kourosh
相关产品推荐
相关产品推荐

