AJAX利用Jsonp进行跨域对MVC项目访问
JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。 案例:一创建一个MVC项目,作为服务端(即:被请求方) (域名:http://localhost:58382/)
Home控制器 namespace MvcApp.Controllers { public class HomeController : Controller { public ActionResult Index() { string callback = this.Request["callback"]; //获取回调函数的名称,的到showMessage string json = "{"name":"server"}"; this.Response.Write(callback + "(" + json + ")"); return new EmptyResult(); } } } 再创建一个MVC项目 ,作为客户端(即:请求方)(域名http://localhost:61497/)
在MvcApp2中创建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) //运行后打印出server } </script> <script src="http://localhost:58382/home/Index?callback=showMessage" type="text/javascript"></script> </head> <body> <div> </div> </body> </html>
-----------MvcApp项目优化 (优化服务端) 主要是自定义一个JsonpResult类,这个类继承了JsonResult类using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Script.Serialization; namespace MvcApp.Controllers { public class HomeController : Controller { public JsonpResult IndexTest() { return this.Jsonp(new { name = "server JsonpResult" }); } } 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 AccessViolationException("context"); } if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod,"GET",StringComparison.OrdinalIgnoreCase)) //如果不允许来自客户端的Get请求,并且请求类型是Get { throw new AccessViolationException(); } var response = context.HttpContext.Response; if (!string.IsNullOrEmpty(ContentType)) //这个ContentType是获取或设置内容的类型。它是JsonResult类中的一个属性 { response.ContentType = ContentType; //设置响应内容的类型 } else { response.ContentType = CallbackApplicationType; //设置响应内容的类型 } if (ContentEncoding != null) { response.ContentEncoding = this.ContentEncoding;//设置响应内容的编码 } if (Data != null) //这个Data是JsonResult类中的一个属性 { string buffer; var request = context.HttpContext.Request; var serializer = new JavaScriptSerializer(); if (request[JsonpCallbackName] != null) //获取回调函数名称(即:获取这个<script src="http://localhost:58382/home/IndexTest?callback=showMessage" type="text/javascript"></script>链接上的callback的值,即获取showMessage) { buffer = String.Format("{0}({1})",request[JsonpCallbackName],serializer.Serialize(Data));//首先根据callback获取获取函数名,然后传入json字符串作为函数参数 } else { buffer = serializer.Serialize(Data); } response.Write(buffer); } } } /// <summary> /// Controller控制器类的扩展方法,即:Controller控制器下扩展一个Jsonp方法,这个方法带一个object类型的参数 /// </summary> public static class ControllerExtension { public static JsonpResult Jsonp(this Controller controller,object data) { JsonpResult result = new JsonpResult() { Data = data,JsonRequestBehavior = JsonRequestBehavior.AllowGet }; return result; } } } 这时候MvcApp2(客户端)来请求 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script> function showMessage(result) { alert(result.name) //打印出:server JsonpResult } </script> <script src="http://localhost:58382/home/IndexTest?callback=showMessage" type="text/javascript"></script> </head> <body> <div> </div> </body> </html> 案例:二直接通过ajax进行跨域请求数据(将dataType的值设为jsonp) 这种方式其中本质也是和案例一是一样的。都是通过Get请求 它最终也是通过请求http://localhost:58382/home/Index?callback=jsonpCallback&_=1481277739025 这个地址,然后服务端拿到callback这个回调函数,然后返回jsonpCallback({"name":"Server"}) 这样的一个函数,这样我们在本地定义的jsonpCallback函数就可以使用了。这样功能跨域就实现了。 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <script src="~/Scripts/jquery-1.8.2.js"></script> </head> <body> <div> </div> </body> </html> <script type="text/javascript"> $.ajax({ url: 'http://localhost:58382/home/Index',//请求的url dataType: "jsonp",//将请求类型设为值jsonp //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonp: "callback",//服务端会通过HttpContext.Request["callback"]; 拿到jsonpCallback这个回调函数的名称 jsonpCallback: "jsonpCallback",//自定义的jsonp回调函数名称"jsonpCallback",返回的json也必须有这个函数名称 success: function (json) { console.log(json); alert(json.name); },error: function (xhr,status,error) { console.log(xhr); } }); </script> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |