You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework 4.8 MVC应用AJAX请求CORS策略问题求助

.NET Framework 4.8 MVC AJAX请求CORS问题解决方案

问题核心

  • 基于.NET Framework 4.8的MVC应用,未使用Web API或.NET Core专属CORS库
  • jQuery AJAX调用控制器Action时触发CORS策略报错,普通非AJAX请求可正常运行
  • 身份验证失败时,控制器会重定向至微软登录页,已通过OWIN实现微软认证

已尝试的无效方案

  • 在web.config中添加CORS响应头配置:
<httpProtocol>
  <customHeaders>
    <clear />
    <add name="Access-Control-Allow-Origin" value="*" />
  </customHeaders>
</httpProtocol>
  • 自定义ActionFilterAttribute并应用到控制器:
public class CustomActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Credentials", "true");
        if (filterContext.HttpContext.Request.HttpMethod == "OPTIONS")
        {
            filterContext.HttpContext.Response.Flush();
        }
        base.OnActionExecuting(filterContext);
    }
}

针对性解决步骤

1. 修复CORS头冲突

当前配置的Access-Control-Allow-Origin: *与Access-Control-Allow-Credentials: true存在冲突——允许携带凭证时,Origin不能设为通配符,必须指定具体请求源域名:

  • 静态指定域名:修改ActionFilter或web.config中的Origin值为前端实际域名,例如:
filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "https://your-frontend-domain.com");
  • 动态支持多域名:在ActionFilter中验证请求Origin后返回对应值:
var allowedOrigins = new List<string> { "https://domain1.com", "https://domain2.com" };
var requestOrigin = filterContext.HttpContext.Request.Headers["Origin"];
if (!string.IsNullOrEmpty(requestOrigin) && allowedOrigins.Contains(requestOrigin))
{
    filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", requestOrigin);
}

2. 正确处理OPTIONS预请求

AJAX跨域请求会先发OPTIONS预请求,原ActionFilter未终止请求流程,导致后续逻辑干扰CORS响应,修改如下:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var response = filterContext.HttpContext.Response;
    var request = filterContext.HttpContext.Request;

    var allowedOrigins = new List<string> { "https://your-frontend-domain.com" };
    var requestOrigin = request.Headers["Origin"];
    if (!string.IsNullOrEmpty(requestOrigin) && allowedOrigins.Contains(requestOrigin))
    {
        response.AddHeader("Access-Control-Allow-Origin", requestOrigin);
    }
    response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    response.AddHeader("Access-Control-Allow-Credentials", "true");
    response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");

    if (request.HttpMethod == "OPTIONS")
    {
        response.StatusCode = 200;
        response.End(); // 终止请求,不执行后续Action逻辑
        return;
    }

    base.OnActionExecuting(filterContext);
}

3. 调整身份验证失败的响应逻辑

跨域AJAX无法跟随重定向到第三方登录页(浏览器会拦截),需区分AJAX与普通请求,返回JSON让前端自行跳转:

  • 修改d.cs的Search动作:
public ActionResult Search()
{
    if (!User.Identity.IsAuthenticated)
    {
        if (Request.IsAjaxRequest())
        {
            return Json(new { Success = false, RedirectUrl = Url.Action("SignIn", "Home") }, JsonRequestBehavior.AllowGet);
        }
        return RedirectToAction("SignIn", "Home");
    }

    // 正常业务逻辑处理
    return View();
}
  • 前端AJAX处理返回结果:
$.ajax({
    url: '/d/search',
    type: 'GET',
    xhrFields: {
        withCredentials: true // 携带身份凭证Cookie
    },
    success: function(result) {
        if (!result.Success) {
            window.location.href = result.RedirectUrl;
        } else {
            // 处理业务数据
        }
    },
    error: function(xhr) {
        if (xhr.status === 401) {
            window.location.href = '/Home/SignIn';
        }
    }
});

4. 检查OWIN中间件顺序

确保OWIN的CORS相关处理(如果配置)在身份验证中间件之前执行,避免身份验证逻辑先触发导致CORS头未正确添加。


内容的提问来源于stack exchange,提问作者M K Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 20:05:03