【笔记】Asp.Net WebApi对js POST带参数跨域请求的支持方案

先说下需求:在原来的WebApi项目中增长对js跨域的请求支持,请求方式:以POST为主,webapi路由规则根据原项目需求修改以下:html

public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

熟悉WebApi的猿猿们都知道这样设置路由规则直接致使了同一个controller中的不一样方法的访问改由方法前的标签决定,而不是方法名来决定。web

关于js跨域的原理以下:假设咱们请求的地址A:http://api.xx.com/api/GetAllPeople,那若是在B页面 http://www.baidu.com/tlzzu.html中使用POST去调用外部接口的话,B页面会先向A地址发送一个OPTIONS类型(OPTIONS并非webapi中的一个方法名,而是一种请求类型,相似POST、GET等)的预检请求(Preflight Request)只要对这种请求返回200就能够,具体内容不做检验。执行成功后会再次对A接口进行正常请求。返回数据。ajax

解决办法:json

若是是Asp.Net MVC或者是WebApi可进行以下设置:api

1.先在Web.config中进行以下设置:跨域

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Origin,X-Requested-With,Content-Type,accept,key" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

注意【Access-Control-Allow-Headers】属性,里面表示iis容许接受的headers的集合,若是没有key则不能在JQuery.ajax中使用beforeSend(或者headers:{"key":"11111"},)方法传递参数.若是在HTTP请求中会在请求头里加入其它属性,则必定要在app

<add name="Access-Control-Allow-Headers" value="Origin,X-Requested-With,Content-Type,accept,key" />cors

中声明。
测试

2.在Global.asax文件中设置:jsonp

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            var req = System.Web.HttpContext.Current.Request;
            if (req.HttpMethod == "OPTIONS")//过滤options请求,用于js跨域
            {
                Response.StatusCode = 200;
                Response.SubStatusCode = 200;
                Response.End();
            }
        }

用于过滤全部的OPTIONS请求

3.在B页面中进行以下请求:

$.ajax({
    type: "POST",
    contentType: "application/x-www-form-urlencoded",
    url: "http://api.xx.com/api/GetAllPeople",
    dataType: "json",
    data:{DM:52,key:"11111"},
    success: function (result) {
        alert(JSON.stringify(result));
    }
});

总结:

遇到问题是须要冷静,建立demo测试的时候demo须要干净,最好全过程从新建立。

另:

1.听说在apicontroller上添加[EnableCors]属性也能够进行跨域访问,不过我没找到,可参考下面文章:ASP.NET Web API自身对CORS的支持: EnableCorsAttribute特性背后的故事

2.jsonp方式的请求只支持GET方式的请求,因此不能知足如今的须要(带参数的POST跨域请求);

3.本文还参考关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案文章

相关文章
相关标签/搜索