Razor MVC中JS Ajax调用Action发布后返回302错误如何解决
问题产生原因
302是HTTP协议中的重定向状态码,你的场景下触发302的原因主要有3个:
- 接口返回逻辑不匹配Ajax调用规则
你在服务端Action里无论执行成功还是失败,都返回RedirectToAction结果,这个结果天生会让MVC框架返回302状态码,附带目标地址到Location响应头。普通表单提交可以正常识别这个响应自动跳转,但Ajax请求默认只会自动跟随重定向拿到最终页面的HTML内容,和你前端配置的dataType: "json"预期的JSON格式完全不匹配,就会触发请求失败。 - Session空值触发认证拦截
你代码里直接读取Session里的门店编码、用户名,没有做空值判断。发布环境IIS的Session默认超时时间是20分钟,用户停留时间过长Session过期后,请求还没走到你的Buy方法逻辑,就会被框架的认证/授权模块拦截,自动返回302跳转到登录页,这也是发布后才频繁出现问题的核心原因——本地调试时Session一直有效,不会触发这个拦截。 - 硬编码路径适配性差
前端写死了请求路径/TessileCart/Buy,如果发布时站点部署在IIS虚拟目录下(不是网站根路径),这个路径会匹配不到对应的路由,被IIS错误模块拦截重定向到404页/首页,也会返回302状态码。
解决方法
根据你的业务场景二选一即可:
方案1:保留Ajax调用,修正前后端交互逻辑(推荐)
- 服务端修改:不要给Ajax请求返回重定向结果,统一返回JSON格式的状态与跳转地址,加上Session空值校验,避免被框架拦截。
修正后的服务端代码参考:[HttpPost] public ActionResult Buy(string offerType, string requestPath, string currency) { try { // 提前校验Session有效性,避免空引用触发框架跳转 if (Session[Global.CodStore] == null || Session[Global.UserName] == null) { return Json(new { success = false, redirectUrl = Url.Action("Login", "Account"), msg = "登录状态已过期,请重新登录" }); } decimal codStore = Convert.ToDecimal(Session[Global.CodStore]); string userName = Session[Global.UserName].ToString(); cartRep.CheckOut(codStore, userName, System.Web.HttpContext.Current, currency); return Json(new { success = true, redirectUrl = Url.Action("Index", "Home", new { offerType = offerType }) }); } catch (Exception ex) { Global.log.WriteLog(this.GetType().Name, "Buy", "", ex, Session[Global.UserName]?.ToString() ?? "Anonymous"); return Json(new { success = false, redirectUrl = Url.Action("Index", "Cart", new { offerType = offerType, requestPath = requestPath, error = Global.ErrorMex }) }); } } - 前端修改:用Razor内置的
Url.Action生成请求地址适配虚拟目录部署,去掉多余的contentType配置(你没有传JSON格式的请求体,不需要这个头),根据服务端返回的结果执行跳转。
修正后的前端代码参考:$("#buyButton").click(function () { $.ajax({ type: "POST", url: '@Url.Action("Buy", "TessileCart")', data: { offerType: '@ViewBag.offerType', requestPath: '@ViewBag.requestPath', currency: currentCurrency }, dataType: "json", error: function () { alert("请求提交失败,请刷新页面后重试"); }, success: function (res) { if (res?.redirectUrl) { window.location.href = res.redirectUrl; } } }); }); - 额外配置检查:发布环境检查站点认证规则,如果Buy接口需要登录才能访问,给接口加
[Authorize]特性,同时在全局配置里指定登录页路径,避免拦截时跳转到系统默认路径。
方案2:去掉Ajax,直接用普通表单提交
如果提交后不需要做无刷新提示,完全没必要用Ajax,直接把按钮放在form表单里,设置表单的action为Buy接口地址,method为post,点击按钮直接提交表单即可。这种场景下服务端的RedirectToAction可以正常工作,不会出现格式不匹配问题,开发成本更低。
内容的提问来源于stack exchange,提问作者Federico Pinciaroli
相关产品推荐
相关产品推荐

