.NET MVC中Ajax Post请求出现403 Forbidden错误求助
排查ASP.NET MVC POST请求403 Forbidden错误
嘿,看起来你碰到了ASP.NET MVC里POST请求被拦截的403 Forbidden问题,这大概率和CSRF防护有关,咱们一步步来捋清楚:
你遇到的错误提示:
Failed to load resource: the server responded with a status of 403 (Forbidden)
你的前端代码(HTML/JQuery)
function AgregarLike(id, num){ alert("Entre:" + id); var urlAction = "@Url.Action("UpdateLikeVisitBrandPhoto", "Report")"; alert (urlAction); var request; // 发起POST请求 request = $.ajax({ url: urlAction + '/' + id, type: "post" }); // 请求成功回调 request.done(function (response, textStatus, jqXHR){ console.log("Hooray, it worked!"); console.log(response); console.log(textStatus) alert("worked"); }); }
控制器代码
public int UpdateLikeVisitBrandPhoto(int id) { try { try { var num = bu.CreateLike(id); } catch { return bu.CreateLike(id); } return bu.CreateLike(id); } catch (ServicesException ex) { logger.Error("", ex); Console.WriteLine(ex); return bu.CreateLike(id); } catch (Exception ex) { logger.Error("", ex); Console.WriteLine(ex); return bu.CreateLike(id); } }
模型代码
public int CreateLike(int id) { using (var sqlConnection = DatabaseUtilities.GetConnection()) { var SQL = "UPDATE [RBAcuerdos].[dbo].[VisitBrandPhoto] SET MeGusta = 1 WHERE id = @paramId"; var sqlCommand = new SqlCommand(SQL, sqlConnection); sqlCommand.Parameters.Add(new SqlParameter("paramId", id)); //sqlCommand.Parameters.Add(new SqlParameter("paramvalue", 1)); return sqlCommand.ExecuteNonQuery(); } //throw new NotImplementedException(); }
可能的原因及解决办法
1. 缺少CSRF令牌验证(最常见原因)
ASP.NET MVC默认会给POST请求做CSRF(跨站请求伪造)防护,要是你的请求里没带CSRF令牌,服务器直接就会返回403。
解决步骤:
- 先在页面里加个CSRF令牌的meta标签:
<meta name="csrf-token" content="@Html.AntiForgeryToken()" />
- 然后在AJAX请求里把令牌加到请求头里:
function AgregarLike(id, num){ alert("Entre:" + id); var urlAction = "@Url.Action("UpdateLikeVisitBrandPhoto", "Report")"; alert (urlAction); // 获取页面里的CSRF令牌 var csrfToken = $('meta[name="csrf-token"]').attr('content'); var request; request = $.ajax({ url: urlAction + '/' + id, type: "post", // 把令牌放进请求头 headers: { 'RequestVerificationToken': csrfToken } }); request.done(function (response, textStatus, jqXHR){ console.log("Hooray, it worked!"); console.log(response); console.log(textStatus) alert("worked"); }); }
- 最后给控制器方法加上
[ValidateAntiForgeryToken]特性(别忘了加[HttpPost]明确请求类型):
[HttpPost] [ValidateAntiForgeryToken] public int UpdateLikeVisitBrandPhoto(int id) { // 原有代码... }
2. 路由匹配问题
你现在是把id拼在URL后面,可能和路由配置不匹配。试试用POST参数传递id,更符合MVC的默认规则:
request = $.ajax({ url: urlAction, type: "post", data: { id: id }, // 用data传参数 headers: { 'RequestVerificationToken': csrfToken } });
3. 用户权限限制
检查下你的控制器或者方法是不是加了[Authorize]特性,如果当前用户没登录或者权限不够,也会返回403。测试阶段可以先把这个特性去掉,确认是不是权限问题。
4. 数据库操作的小问题(不是403直接原因,但得修)
你的模型代码里没打开数据库连接,得加上sqlConnection.Open();,不然数据库操作会失败:
public int CreateLike(int id) { using (var sqlConnection = DatabaseUtilities.GetConnection()) { sqlConnection.Open(); // 打开连接! var SQL = "UPDATE [RBAcuerdos].[dbo].[VisitBrandPhoto] SET MeGusta = 1 WHERE id = @paramId"; var sqlCommand = new SqlCommand(SQL, sqlConnection); sqlCommand.Parameters.Add(new SqlParameter("paramId", id)); return sqlCommand.ExecuteNonQuery(); } }
建议先从CSRF令牌的问题入手排查,这是POST请求返回403最常见的原因。
内容的提问来源于stack exchange,提问作者Javi
相关产品推荐
相关产品推荐

