ASP.NET Ajax登录后调用RedirectToAction返回302/500无法跳转如何解决
问题根因
Ajax异步请求的特性决定了后端返回的302跳转只会让Ajax请求本身跟随重定向拉取目标页面内容,不会触发浏览器整页跳转。同时你指定了dataType: "json",Ajax收到非JSON格式的响应内容(重定向后的HTML)就会触发错误回调。
解决方案
调整逻辑为:后端返回JSON标识登录结果和跳转地址,前端收到成功响应后主动执行跳转,修改代码如下:
1. 后端修改
将登录成功分支的RedirectToAction替换为JSON返回,同时补充returnUrl合法性校验避免报错和安全问题:
case SignInStatus.Success: // 先校验returnUrl是本地地址,避免开放重定向漏洞 if (!Url.IsLocalUrl(returnUrl)) { // 非法地址跳转到默认首页,可根据实际业务调整 returnUrl = "Home/Index"; } string[] parsedUrl = returnUrl.Split('/'); // 校验split后的数组长度避免索引越界触发500错误 if(parsedUrl.Length < 2) { returnUrl = "Home/Index"; parsedUrl = returnUrl.Split('/'); } // 生成正确的跳转地址返回给前端 var redirectUrl = Url.Action(parsedUrl[1], parsedUrl[0]); return Json(new { success = true, redirectUrl = redirectUrl });
其他需要跳转/返回视图的分支也按照同样逻辑修改为JSON返回,例如需要跳转SendCode的分支:
case SignInStatus.RequiresVerification: var verifyUrl = Url.Action("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); return Json(new { success = true, redirectUrl = verifyUrl });
参数校验失败、登录失败的分支也统一返回JSON格式,避免响应格式不匹配报错:
if (!ModelState.IsValid) { return Json(new { success = false, message = "参数错误" }); } // ... case SignInStatus.Failure: return Json(new { success = false, message = "用户名或密码错误" }); default: return Json(new { success = false, message = "登录失败,请重试" });
2. 前端修改
在Ajax的success回调中新增登录成功后的跳转逻辑:
$.ajax({ type: "POST", url: '/Account/Login', data: data, contentType: "application/x-www-form-urlencoded; charset=utf-8", dataType: "json", // 保留json配置,后端已统一返回json格式 success: function (response) { console.log(response) if (response.success) { // 登录成功,主动触发页面跳转 window.location.href = response.redirectUrl; } else { onFail(response.message || "Your username or password is incorrect.", login); } }, error: function (response) { console.log(response) onFail("Internal error, please try again", login) } })
额外说明
之前移除dataType: "json"后返回500的原因大概率是直接对returnUrl做Split操作时,returnUrl格式不符合预期导致数组索引越界抛出异常,上述后端修改中补充的参数校验逻辑可以避免该问题。
内容的提问来源于stack exchange,提问作者AhSoHard
相关产品推荐
相关产品推荐

