Js+MVC~公用API的设计,返回jsonp后使ajax的error属性生效!

相关知识说明

  项目用公用的API事实上就是其它子项目,包括非子项目需要从这个项目中得到一个公用的信息,这种产生信息的接口我们称为公用的API(application program interface),例如:一个A网站,它有用户模块,产品模块,订单模块,帮助中心模组成,而在A网站旗下有它的A论坛,A社区,A微博等,而这些子网站的用户来源是从A网站来的,而如果在子网站中希望得到用户的详细信息,就需要我们在主网站提供一个开放的API,而这个API是如果通过GET请求直接访问的,这是正常的,但如果在A微博中需要异步得到信息,即以ajax方式得到信息,直接访问是不可以的,必须使用jsonp的方式!而对于jsonp来说,如果主网站的接口出现问题了,在默认情况下是不能通知到子网站的,这是jsonp自己的事,而jquery也提供了应对的方法,那就是jquery.jsonp插件,可以在这里下载

说干就干

对于MVC开发环境来说,在视图渲染上提供了对html,javascript,text,json等渲染方式,如果jsonp来说,mvc本身并没有提供,事实上jsonp只是向页面输出json文本信息的变种,我们完全可以自己去伪造一个,当然把它封装的好一些就是要继承JsonResult,并在渲染方法ExecuteResult作一个文章就可以了,看代码:

 1   /// <summary>

 2     /// 返回jsonp上下文

 3     /// </summary>

 4     public class JsonpResult : JsonResult

 5     {

 6         const string CALLBACKNAME = "callback";

 7         /// <summary>

 8         /// 复写渲染视图方法

 9         /// </summary>

10         /// <param name="context"></param>

11         public override void ExecuteResult(ControllerContext context)

12         {

13             if (context == null)

14             {

15                 throw new ArgumentNullException("当前请求上下文出错");

16             }

17             if ((JsonRequestBehavior == JsonRequestBehavior.DenyGet)

18                 && String.Equals(context.HttpContext.Request.HttpMethod, "GET"))

19             {

20                 throw new InvalidOperationException("Jsonp只能是GET请求");

21             }

22             var response = context.HttpContext.Response;

23             if (!String.IsNullOrEmpty(ContentType))

24             {

25                 response.ContentType = ContentType;

26             }

27             else

28             {

29                 response.ContentType = "application/json";

30             }

31             if (ContentEncoding != null)

32             {

33                 response.ContentEncoding = this.ContentEncoding;

34             }

35             if (Data != null)

36             {

37                 String buffer;

38                 var request = context.HttpContext.Request;

39                 var serializer = new JavaScriptSerializer();

40                 if (request[CALLBACKNAME] != null)

41                     buffer = String.Format("{0}({1})", request[CALLBACKNAME], serializer.Serialize(Data));

42                 else

43                     buffer = serializer.Serialize(Data);

44                 response.Write(buffer);

45             }

46         }

47     }

而对于公用的API来说,我们可以在controller里这样去写:

 1      /// <summary>

 2         /// 跨域API

 3         /// </summary>

 4         /// <returns></returns>

 5         public JsonpResult GetUserAPI(string userID)

 6         {

 7             JsonpResult result = new JsonpResult()

 8             {

 9                 Data = new { name = "zzl", res = true, },

10                 JsonRequestBehavior = JsonRequestBehavior.AllowGet

11             };

12             return result;//反回一个callback(msg)对象

13         }

OK,底层获到公用信息的工作已经完成了,再看一下如何在A微博页面上去调用它:

 1  //跨域调用公用的API,如果希望它相应error事件,需要使用$.jsonp,而不是JQ的$.ajax

 2     function jsonpFun() {

 3         $.ajax({

 4             dataType: 'jsonp', //跨域使用它

 5             jsonp: 'callback', //可以省略,但如果显示声明它,必须是callback,因为在JsonResult里jsonp字符串已经被规定成它了

 6             url: 'http://www.jsonp.com/Common/GetUserAPI',

 7             data: { userID: 1 },

 8             type: 'GET',

 9             success: function (data) {

10                 alert(data.name);

11             },

12             error: function (data) {

13                 alert("获取用户信息失败");

14             }

15         });

16     }

上面的代码应该改为:

 1       $.jsonp({

 2             url: 'http://www.jsonp.com/Common/GetUserAPI?userID=1',

 3             callbackParameter: 'callback',

 4             success: function (data) {

 5                 alert(data.name);

 6             },

 7             error: function (xOptions, textStatus) {

 8                 alert("获取用户信息失败");

 9             }

10         });

 

好了,前面已经说了对于jsonp来说,ajax的error属性是不好使的,我们需要在页面上引用jquery.jonsp这个js插件才行:

1 <script src="http://www.cnblogs.com/Scripts/jquery.jsonp-2.3.0.min.js" type="text/javascript"></script>

OK,我们测试一下吧:

没有问题,信息已经得到了,再看看fiddler所捕获的消息:

我们的URL上自己加上了callback,而这个串是A网站与A微博网站自己规定的,如果您不知道它们的规范,这个请求是会失败的,这是正常的,呵呵。

通过GET请求,直接可以返回你要的字符,这也是正常的,当然实现项目中,我们会在双方进行密文的设计的!

你可能感兴趣的:(返回JSON)