1、客戶端用JSONP請求數據javascript
若是你想用JSONP來得到跨域的數據,WebAPI自己是不支持javascript的callback的,它返回的JSON是這樣的:html
{"YourSignature": "嫁人要嫁程序員,錢多話少死得早"}
然而,JSONP請求指望獲得這樣的JSON:java
jQuery123456({"YourSignature": "嫁人要嫁程序員,錢多話少死得早"})
因此咱們須要對WebAPI作拓展,讓它支持這樣的callback。我找到了兩種辦法。程序員
本身寫個Attribute,來給返回的JSON包上callbackweb
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:ajax
[JsonCallback] [HttpGet] public HttpResponseMessage a() { string strJson = "{\"info\" : \"true\"}"; var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(strJson, Encoding.UTF8, "text/plain") }; return result; }
很是簡潔明瞭,可是這種方法有個缺點,就是被加了[JsonCallback]的方法,只能適用於JSONP的請求。若是你但願API能被各類場合的客戶端調用,仍是在服務端提供支持吧。json
2. 經過自定義JsonMediaTypeFormatter實現api
參見 Artech大神的文章:http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-03.html跨域
蔣大神的文章的JsonpMediaTypeFormatter類只適合將對象傳過去進行json序列化,有點弊端app
支持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兩個參數去掉,就確定不會爆了!!!