在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、客户端用JSONP请求数据 如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的: {"YourSignature": "给我钱"} 然而,JSONP请求期望得到这样的JSON: jQuery123456([{"YourSignature": "给我钱"}]) 所以我们需要对WebAPI做拓展,让它支持这样的callback。我找到了两种办法。 1. 来自stackoverflow的方案: http://stackoverflow.com/questions/9421312/jsonp-with-asp-net-web-api/18206518#18206518 自己写个Attribute,来给返回的JSON包上callback public class JsonCallbackAttribute : ActionFilterAttribute { private const string CallbackQueryParameter = "callback"; public override void OnActionExecuted(HttpActionExecutedContext context) { var callback = string.Empty; if (IsJsonp(out callback)) { var jsonBuilder = new StringBuilder(callback); jsonBuilder.AppendFormat("({0})", context.Response.Content.ReadAsStringAsync().Result); context.Response.Content = new StringContent(jsonBuilder.ToString()); } base.OnActionExecuted(context); } private bool IsJsonp(out string callback) { callback = HttpContext.Current.Request.QueryString[CallbackQueryParameter]; return !string.IsNullOrEmpty(callback); } } 然后在要被调用的方法前加上这个Attribute: [JsonCallback] public IEnumerable<User> User() { return _user; } 非常简洁明了,但是这种方法有个缺点,就是被加了[JsonCallback]的方法,只能适用于JSONP的请求。如果你希望API能被各种场合的客户端调用,还是在服务端提供支持吧。 2. 通过自定义JsonMediaTypeFormatter实现 参见 Artech大神的文章: http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-03.html 二、服务端实现 方法一:支持CORS最地道的方法当然是在服务端提供支持,按官网的办法,100%成功。 http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api 1. 到nuget上装一个包: http://www.nuget.org/packages/Microsoft.AspNet.WebApi.Cors/ 2. 在WebApiConfig.Register方法中加入代码: config.EnableCors(); 3. 在Controller上加上Attribute: [EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*", methods: "*")] 这个域名是可以配置的,具体还请参考上面给出的官网教程。 最后,还要告诉大家一个坑,在服务端完提供支持以后,不要高兴的太早,如果你用jQuery.ajax()的方式去请求,还是会爆的: $.ajax({ url: 'yourCORSurl', data: '', dataType: 'json', type: 'GET', contentType: 'application/json; charset=utf-8', ... }) 经过无数次爆破,终于发现,只要 把dataType和contentType两个参数去掉 方法二:配置 web.config 在 <system.webServer> 标签内添加以下代码 <httpProtocol> 然而这里以为搞掂收工,谁知还有一个大坑 当你发送请求时,它居然把OPTIONS类型的请求给撸掉了!在jQuery等框架里发起CORS请求的时候,虽然你写的可能是“GET”,但是现在的浏览器是会自动把这个GET先撸成OPTIONS去访问服务的,这也叫“preflight”请求。如果你的服务拒绝OPTIONS这个verb,你会得到一个405的结果(用fiddler就可以看到)。 所以,要让WebAPI支持CORS,第一步就是在web.config里把“ <remove name="OPTIONSVerbHandler" /> ”删掉。
现在就可以正常访问了。
注意: 当使用方法一的时候,放在web Api的静态文件资源,比如图片,后台把图片路径传给前台后,前台通过jq想把图片转成base64 就发生跨域问题, 如果需要实现,只能采用第二种方法。 |
请发表评论