JQuery getJSON方法的总结

最近在新公司的项目里面经常用到JQuery的getJSON方法和后台程序进行交互,所以特意来总结一下,以备以后的项目的需要。
jQuery中常用getJSON来调用并获取远程的JSON字符串,将其转换为JSON对象,如果成功,则执行回调函数。原型如下:
jQuery.getJSON( url, [data], [callback] )
url:必需 规定将请求发送的哪个 URL
data : (可选) 规定连同请求发送到服务器的key/value数据
callback: (可选) 载入数据成功时的回调函数

例如:
   function LoginSubmit(memberDomain) {
    if (document.getElementById("Account").value == "" || document.getElementById("Password").value == "") {
        alert("用户名或密码不能为空?");
    } else {
        $.getJSON(memberDomain + "/Login/LoginIndex?jsoncallback=?", {
            account: document.getElementById("Account").value,
            password: document.getElementById("Password").value,
            rnum: Math.random()
        }, function (result) {
            if (result.IsSuccess) {
                loginPanelInit(memberDomain);
            }
            else {
                alert("登录不成功!");
            }
        });
    }
}
上面getJSON url部分的memberDomain表示域名,getJSON支持跨域调用,Login表示ASP.NET MVC里面控制器Controller的名字,LoginIndex表示Action的名字.URL后面跟的jsoncallback=?表示该请求是JQuery的JSONP请求.

JQuery官方的网站对getJSON方法的英文解释说明了这一点。
If the URL includes the string "callback=?" (or similar, as defined by the server-side API), the request is treated as JSONP instead. See the discussion of the jsonp data type in $.ajax() for more details.

JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。这种跨域的通讯方式称为JSONP。
很明显,JSONP是一种脚本注入(Script Injection)行为,需要特别注意其安全性。

jQuery对JSONP请求的封装方式很值得提倡:

$.getJSON(url, params + "&jsoncallback=?", function(json){
    /* do something */
});

用jsoncallback作为服务器端支持的标准jsonp参数,而每次执行这个方法都会用时间戳生成一个唯一的全局函数名,替换这个“?”,这个细节被封装到黑盒里,使用者不必了解,可以像普通的ajax请求一样,用匿名的回调函数作为最末尾的参数(这是jquery强调的风格),这种语法糖(syntactic sugar)的作用绝对不仅仅是让前端开发人员可以偷懒而已,对代码的可读性,兼容性和今后的维护都有好处。


Jsonp原理:

首先在客户端注册一个callback, 然后把callback的名字传给服务器。

此时,服务器先生成 json 数据。

然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

注意:
1.运用JQuery的进行跨域调用时请求地址一定要有 jsoncallback=? ,例如我请求 百度,传一个参数userName=123,应该这样写:http://www.baidu.com?userName=123&jsoncallback=? ,如果我不传参数userName,应该这样写:http://www.baidu.com?jsoncallback=?

2、第二个参数一定要是json格式键/值对的格式。例:{ "email": ""}

3、回调函数,您请求的地址需要返回数据,返回的数据必须是严格的json格式的数据,还需要用参数jsoncallback加小括号包裹jsoncallback(json格式的数据),否则就会出现回调函数不会执行的问题。
如下面控制器返回的数据是就是这种格式jsoncallback(SerializeHelper.JsonSerialize(viewData))。
return Content(string.Format("{0}({1})", jsoncallback, SerializeHelper.JsonSerialize(viewData)), "text/plain", System.Text.Encoding.UTF8);

JQuery跨域调用的后台方法:
public ActionResult LoginIndex(string account, string password)
        {
            string jsoncallback = Request.QueryString["jsoncallback"];
            bool tag = true;
            loginInfo dto = new loginInfo();
            dto.Account = account;           
            dto.AccountError = "";
            JsonViewData viewData = new JsonViewData() { IsSuccess = false, ErrorMessage = "登录失败" };
            password = CryptographyHelper.MD5(CryptographyHelper.MD5(password));

            MembershipDTO mdto = MembershipBiz.Instance.Login(account, password);

            if (mdto != null)
            {
                if (mdto.Status >= 0)
                {
                    string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
                    MembershipBiz.Instance.LogionUpdate(mdto.MembershipId, ip);
                    UpdateCredit(mdto.MembershipId, ip);
                }
                else
                {
                    dto.AccountError = "该用户不存在";
                    tag = false;
                    viewData.IsSuccess = false;
                }
            }
            else
            {
                dto.AccountError = "帐号或者密码错误";
                tag = false;
                viewData.IsSuccess = false;
            }
            if (tag)
            {
                Security.Authentication.Authenticate(account, password, false);
                viewData.IsSuccess = true;
                return Content(string.Format("{0}({1})", jsoncallback, SerializeHelper.JsonSerialize(viewData)), "text/plain", System.Text.Encoding.UTF8);

            }
            else
            {
                viewData.IsSuccess = false;
                return Content(string.Format("{0}({1})", jsoncallback, SerializeHelper.JsonSerialize(viewData)), "text/plain", System.Text.Encoding.UTF8);
            }
        }


JQuery getJSON的等价形式$.ajax()或者JQuery.ajax().这种形式相比$.getJSON形式更加的具体,通过设置不同的参数控制起来更加的灵活。比如在某些特殊情况下可以将请求由异步改为同步async: false,请求的类型可以设置为"post"等。
如下所示:
   function GetSupplyNum(id) {
         var childnum = "";
         jQuery.ajax({
             type: "get",
             async: false,
             url: "/Default1/GetSupplyCountByCategory",
             data: 'id=' + id + '',
             contentType: "text",
             dataType: "json",
             cache: false,
             success: function (data) {
             childnum = childnum + data;
             }
         });
         return childnum;
     }
posted @ 2012-08-22 11:49  美梦成真  阅读(984)  评论(0编辑  收藏  举报