今天我们遇到了一个CORS跨域的问题
Ajax如下
var url = "http://localhost:11980/api/Demo/GetString"; //api地址 $.ajax({ type: "get", url: url, data: null, headers: { SecretKey: "ec8b570ad4bd403783c52ecb5cdfa849", AppKey: "1259402909", UniqueKey: "987654321" }, success: function (data) { alert(data); } });
如果把 headers 去掉,CORS跨域是没有问题的,但是加上就完犊子了
解决方案
Global 文件中添加一下代码
protected void Application_BeginRequest(object sender, EventArgs e) { var res = HttpContext.Current.Response; var req = HttpContext.Current.Request; //自定义header时进行处理 if (req.HttpMethod == "OPTIONS") { res.AppendHeader("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name,Token,Cookie,SecretKey,UniqueKey,AppKey"); res.AppendHeader("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS"); res.AppendHeader("Access-Control-Allow-Origin", "*"); res.StatusCode = 200; res.End(); } }
Filters
public class ActionAuthFilters : ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Headers", "*"); actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Methods", "*"); base.OnActionExecuted(actionExecutedContext); } }
Action
[ActionAuthFilters] [HttpGet] public string GetString() { return "OK"; }
解决问题
解释为啥
因为 ajax 中添加了 headers
所以浏览器会发送两次请求
第一次是OPTIONS 类型的请求,这个请求会询问服务器支持哪些请求方法(GET,POST等),支持哪些请求头等等服务器的支持情况。等到这个请求返回后,如果原来我们准备发送的请求符合服务器的规则,那么才会继续发送第二个请求,否则会在Console中报错。
第二次才是我们写的那个 Get Post 请求
所以需要在 Application_BeginRequest 中判断如果是OPTIONS 类型的请求 直接返回OK,并且告诉浏览器我们支持什么类型的请求,参数,URL
然后浏览器根据 Application_BeginRequest 中的配置在进行后续的操作