如何使用async/await实现JavaScript 100%稳定页面重定向
异步场景下页面重定向偶发失效修复方案
问题现象
- 页面跳转逻辑偶发失效:部分场景下可正常完成重定向,部分场景下仅刷新当前页面,无法实现100%成功跳转
- 已尝试4种常见JavaScript重定向写法均未解决问题,试过的写法如下:
window.location = myurl; window.location.href = myurl; window.location.assing(myurl); // 注意:此处存在方法名拼写错误 window.location.replace(myurl);
根因定位
核心触发原因是点击事件回调未等待异步请求执行完成,浏览器默认行为冲掉了重定向逻辑,具体问题点如下:
- 按钮点击绑定的
searchCar是同步函数,内部调用异步方法getCheckOutOfHrs时没有加await等待,异步请求返回前浏览器会继续执行按钮的默认行为(如果按钮是表单提交类型,会直接触发表单提交刷新当前页) - 代码存在笔误:
window.location.assing()方法名拼写错误,正确写法为window.location.assign(),该写法执行时会直接抛出JS异常,阻断后续逻辑 - 异常分支无兜底:
fetch请求失败、接口返回结构不符合预期时,代码会直接进入catch块终止执行,没有任何跳转逻辑,表现为停在当前页/刷新当前页 - 代码残留
debugger语句:部分浏览器环境下,未开启开发者工具时debugger会阻塞JS线程执行,导致后续跳转逻辑不运行 - 冗余逻辑干扰:代码中声明的
AbortController从未调用abort()方法,属于无效代码,部分浏览器下可能引发请求意外中断
修复后可直接运行的代码
// 按钮事件绑定 $('#btn-search-car').click(function(e) { searchCar(e) }); /** * 查车逻辑 */ async function searchCar(e) { try { // 阻止默认行为+事件冒泡,避免提前触发表单提交 e.preventDefault(); e.stopPropagation(); var obj = { Branch: lStrLocNam.trim(), PickupLocId: lIntPickupLocId, FranchiseId: lIntFranchiseId, SubofficeId: lIntSubofficeId, StartDate: dtStart, StartTime: startTime, EndDate: dtEnd, EndTime: endTime, VehicleType: selectedVehType, VehicleCategoryId: carCat, IsNewSearch: true }; saveElement('SelectedParamInSearch', obj); // 等待异步校验完成,再执行后续逻辑 await getCheckOutOfHrs(obj); } catch (err) { // 异常场景兜底跳转,避免卡当前页 const fallbackUrl = "/Home/FindBranch/?franchiseId=" + lIntFranchiseId; window.location.href = fallbackUrl; } }; /** * 非营业时间校验+跳转逻辑 */ const getCheckOutOfHrs = async(obj) => { let resultPages = []; const apiUrl = REACT_APP_CheckOutOfHours; const requestConfig = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(obj) }; const redirectUrl = "/Home/FindBranch/?franchiseId=" + obj.FranchiseId; try { const response = await fetch(apiUrl, requestConfig); if (response && response.ok) { resultPages = await response.json(); } const outOfHoursRes = resultPages; // 满足弹窗提示条件则弹窗,其余场景统一跳转 if (outOfHoursRes?.length !== 0 && outOfHoursRes?.item2) { saveElement('OutOfHoursParam', outOfHoursRes); if (outOfHoursRes.item2.indexOf("£") < 0) { alert(outOfHoursRes.item2); return; } } // 执行跳转,使用href赋值兼容性最好 window.location.href = redirectUrl; } catch (error) { // 请求异常直接走兜底跳转 window.location.href = redirectUrl; } };
落地注意事项
- 如果跳转按钮放在
<form>表单内部,需要额外给表单绑定submit事件,在事件内调用e.preventDefault()阻止默认表单提交刷新行为 - 生产环境必须删除所有
debugger语句,避免阻塞JS执行 - 重定向优先使用
window.location.href = 目标地址的写法,兼容性覆盖所有主流浏览器;如果不需要保留当前页面在浏览历史中,可以替换为window.location.replace(目标地址) - 所有依赖异步返回结果的逻辑,必须在
await等待异步执行完成后再运行,避免主线程提前执行默认逻辑干扰业务流程
内容的提问来源于stack exchange,提问作者maifs
相关产品推荐
相关产品推荐

