Jsonp简单认识(后端使用的是asp.net mvc)

2016-12-29 09:55:23来源:oschina作者:hujiapeng人点击

一、Jsonp简介:由于浏览器基于安全有同源策略(同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性)机制,所以前端无法使用Ajax来获取来获取其他域名下返回的数据,而Jsonp可以实现跨域访问。


  Jsonp是基于
29
30 View Code

3、在OtherDomain项目中新增HomeController及其视图,HomeController中代码如下:


using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace OtherDomain.Controllers { public class HomeController : Controller { //
// GET: /Home/
public ActionResult Index() { return View(); } public ActionResult SomeJsonp() { return new ContentResult() { //myCallBack为服务端与前端约定好的函数
Content = "myCallBack(" + JsonConvert.SerializeObject(new { Name = "Tom", Age = 23 }) + ")", ContentType = "text/html" }; } } }View Code

4、启动两个项目,点击JsonpDemo项目页面中的按钮,谷歌浏览器控制台下看到



三、对上面Demo做一下简单优化,可以通过前端来指定与服务器约定的函数


1、修改JsonpDemo项目index.cshtml页面中,按钮点击事件下CreateScript方法传入参数为:http://localhost:55157/home/somejsonp?callback=myCallBack 也就是加上一个URL参数


2、修改OtherDomain项目下HomeController.cs中SomeJsonp方法如下:

public ActionResult SomeJsonp() { string func = Request.Params["callback"]; return new ContentResult() { Content = func+"(" + JsonConvert.SerializeObject(new { Name = "Tom", Age = 23 }) + ")", ContentType = "text/html" }; }

四、通过jQuery使用Jsonp实现跨域请求


1、继续沿用上面两个项目,修改JsonpDemo项目index.cshtml页面代码,新增一个按钮,并实现其click事件相关代码,如下:


@{ Layout = null; }



Index









View Code

注意上面ajax参数dataType为jsonp,jsonp为callback


2、OtherDomain下HomeController.cs文件SomeJsonp代码和第三个里面代码一样,如下:


public ActionResult SomeJsonp() { string func = Request.Params["callback"]; return new ContentResult() { Content = func + "(" + JsonConvert.SerializeObject(new { Name = "Tom", Age = 23 }) + ")", ContentType = "text/html" }; }View Code

3、运行两个项目,点击“get jsonp by jquery”按钮,可以在谷歌浏览器控制台下看到同样结果



4、注意:如果前端代码传入callback参数,那么前端也要自己实现相应参数的函数。如果没有传入,其实jQuery自己会默认传入并自己实现。


五、扩展:在OtherDomain项目下,简单自定义JsonpResult类,代码如下:


1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Web;5 using System.Web.Mvc;6
7 namespace OtherDomain8 {9 public class JsonpResult : JsonResult 10{ 11private const string CALLBACK_QUERYSTRING = "callback"; 12//private const string CALLBACK_CONTENTTYPE = "application/x-javascript";
13private const string CALLBACK_CONTENTTYPE = "text/javascript"; 14
15public override void ExecuteResult(ControllerContext controllerContext) 16{ 17if (controllerContext != null) 18{ 19 var request = controllerContext.HttpContext.Request; 20 object callback = request[CALLBACK_QUERYSTRING]; 21 if (callback == null) 22{ 23 controllerContext.RouteData.Values.TryGetValue(CALLBACK_QUERYSTRING, out callback); 24} 25
26 var hasCallback = !string.IsNullOrWhiteSpace(callback == null ? "" : callback as string); 27 if (hasCallback) 28{ 29SetContentTypeIfEmpty(); 30 var response = controllerContext.HttpContext.Response; 31response.Write(callback); 32 response.Write("("); 33 base.ExecuteResult(controllerContext); 34 response.Write(")"); 35} 36 else
37{ 38 base.ExecuteResult(controllerContext); 39} 40} 41} 42
43private void SetContentTypeIfEmpty() 44{ 45if (string.IsNullOrWhiteSpace(base.ContentType)) 46{ 47 base.ContentType = CALLBACK_CONTENTTYPE; 48} 49} 50} 51
52 public static class ContollerExtensions 53{ 54public static JsonpResult Jsonp(this Controller controller, object data, JsonRequestBehavior behavior = JsonRequestBehavior.DenyGet) 55{ 56JsonpResult result = new JsonpResult(); 57result.Data = data; 58result.JsonRequestBehavior = behavior; 59return result; 60} 61} 62 }JsonpResult及ContollerExtensions

如果想要很好的结合到controller中,需要写如上ContollerExtensions的Controller的扩展方法


在OtherDomain项目下,需要修改SomeJsonp方法:

  public ActionResult SomeJsonp() { return this.Jsonp(new { Name= "Tom", Age=23 }, JsonRequestBehavior.AllowGet); }

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台