1:原理在js中,XMLHttpRequest是不能請求不同域的數(shù)據(jù),但是script標(biāo)簽卻可以,所以可以用script標(biāo)簽實現(xiàn)跨域請求。具體是定義一個函數(shù),例如jsonp1234,請求不同域的url時帶上函數(shù)名,例如:http:///index?callback=jsonp1234,然后服務(wù)端根據(jù)callback獲取這個函數(shù)名,然后傳入json字符串作為函數(shù)參數(shù)。 2:實現(xiàn)http://localhost:62203/home/index頁面代碼如下 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script> function showMessage(result) { alert(result.name) } </script> <script src="http://localhost:16308/home/index?callback=showMessage" type="text/javascript"></script> </head> <body> <div> </div> </body> </html> 主要是這句 <script src="http://localhost:16308/home/index?callback=showMessage" type="text/javascript"></script>, 可以看到,訪問的是不同的站點,并且callback的參數(shù)值為showMessage, http://localhost:16308/home/index代碼如下 public ActionResult Index() { string callback = this.Request["callback"]; string json="{\"name\":\"server\"}"; this.Response.Write(callback + "(" + json + ")"); return new EmptyResult(); } 根據(jù)callback獲取函數(shù)名,然后將json字符串作為函數(shù)參數(shù)。 訪問頁面http://localhost:62203/home/index,效果如下 可見,站點localhost:62203從站點localhost:16308獲取到了數(shù)據(jù)。
但是我們看服務(wù)端的實現(xiàn),這也太不美觀,也比較麻煩。 public ActionResult Index() { string callback = this.Request["callback"]; string json="{\"name\":\"server\"}"; this.Response.Write(callback + "(" + json + ")"); return new EmptyResult(); } 我們想要的是調(diào)用一個方法,就能實現(xiàn)跨域了,那如何實現(xiàn)呢??吹紺ontroller有個this.Json 方法,類型是JsonResult,我們可以參考這個類。定義一個類JsonpResult,派生于JsonResult,在ExecuteResult 方法根據(jù)callback獲取函數(shù)名,然后傳入json字符串作為函數(shù)參數(shù)。 public class JsonpResult : JsonResult { public static readonly string JsonpCallbackName = "callback"; public static readonly string CallbackApplicationType = "application/json"; public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if ((JsonRequestBehavior == JsonRequestBehavior.DenyGet) && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException(); } var response = context.HttpContext.Response; if (!String.IsNullOrEmpty(ContentType)) response.ContentType = ContentType; else response.ContentType = CallbackApplicationType; if (ContentEncoding != null) response.ContentEncoding = this.ContentEncoding; if (Data != null) { String buffer; var request = context.HttpContext.Request; var serializer = new JavaScriptSerializer(); if (request[JsonpCallbackName] != null) buffer = String.Format("{0}({1})", request[JsonpCallbackName], serializer.Serialize(Data));//首先根據(jù)callback獲取獲取函數(shù)名,然后傳入json字符串作為函數(shù)參數(shù) else buffer = serializer.Serialize(Data); response.Write(buffer); } } } JsonpResult類有了,但是想在Controller這樣使用this.Jsonp,所以為Controller類定義一個擴(kuò)展方法, public static class ControllerExtension { public static JsonpResult Jsonp(this Controller controller, object data) { JsonpResult result = new JsonpResult() { Data = data, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; return result; } } 這是在Controller就可以直接使用this.Jsonp了,把跨域服務(wù)端的代碼改下 public ActionResult Index() { return this.Jsonp(new { name = "server JsonpResult" }); } 相比上面那個簡潔多了 再次打開http://localhost:62203/home/index 同樣,站點localhost:62203從站點localhost:16308獲取到了數(shù)據(jù),和上面的一樣 |
|
來自: 昵稱10504424 > 《工作》