首页 新闻 会员 周边

请教一个关于jsonp调用的问题

0
悬赏园豆:20 [已解决问题] 解决于 2015-08-04 16:41

我在网上找了jsonp的资料之后,在实践过程中与网站说的不太一致..

先说一下我对jsonp的理解,大家看一下概念上有没有什么问题..

它是一种调用方式,等价于<script src="http://跨域/xxx.js"></script>这样的返回结果.

结果也是js数据,可是以js函数,语句,或是对象.

在用ajax调用时,指定了dataType:"jsonp"后,error:function(){..}函数不会被触发,但是success:function(data){..}函数是会触发的,在调用完成后,如果没有明确指定回调函数的话,直接将结果传入success函数后,将给函数内的代码来处理..

 

我看网站有人在success函数中将返回的li集合添加到body中...那么必定是进入了success函数的了.

 

可是我在实验的过程中,无论如何它就是不进入success,很是不解啊..为什么别人的可以?

好吧,不进入就算了,我给你明确指定一个回调函数,让你把返回的数据传入到我指定的函数中,我在函数中做处理...可是,它还是不理我指定的函数,无视我的指定...

 

好了,我把代码图放上来,请大家帮我找找它不听话的原因...

后台代码:

前台代码:

 

开始我后台代码只写一句 return "alert('CallOK')";调用完成时会弹出对话框的.

可是仍然不进入success:function(data){alert('success');},它也把我的success方法无视了.

 

我还在网上看到这样的说法,如果不指定回调函数,jq会自动生成一个回调函数,将返回的结果传进去执行,jq生成的函数应该不包涵具体逻辑,我猜它可能就是 function xxx(data){data();}这样了.

那么我就疑惑了,是不是前端无法写任何逻辑?比如取出对象数组,遍历后绑定到列表中之类.

连这样的逻辑也要写在后台,拼成js代码的字符串,再返回给前端执行吗?..哦..千万别这样!

 

说了这么多,只想问题大家2个问题:

1,大家在使用的过程中,success方法有没有进入?如果有,你是怎么做到的.

2,自己指定的回调函数,如何才能被它回调执行.

 

谢谢各位了.

问题补充:

补充一下:

我在网站看到的资料是这样的:

var qsData = {'searchWord':$("#searchWord").attr("value"),'currentUserId':
$("#currentUserId").attr("value"),'conditionBean.pageSize':$("#pageSize").attr("value")};

$.ajax({ 
    async:false, 
       url: http://跨域的dns/document!searchJSONResult.action, 
       type: "GET", 
       dataType: 'jsonp', 
       jsonp: 'jsoncallback', 
       data: qsData, 
       timeout: 5000, 
       beforeSend: function(){ 
           //jsonp 方式此方法不被触发.原因可能是dataType如果指定为jsonp的话,就已经不是ajax事件了 
       }, 
       success: function (json) {//客户端jquery预先定义好的callback函数,成功获取跨域服务器上的json数据后,会动态执行这个callback函数 
        if(json.actionErrors.length!=0){ 
              alert(json.actionErrors); 
         } 
           genDynamicContent(qsData,type,json); 
       }, 
       complete: function(XMLHttpRequest, textStatus){ 
        $.unblockUI({ fadeOut: 10 }); 
       }, 
       error: function(xhr){ 
        //jsonp 方式此方法不被触发.原因可能是dataType如果指定为jsonp的话,就已经不是ajax事件了 
        //请求出错处理 
        alert("请求出错(请检查相关度网络状况.)"); 
       } 
});
hexllo的主页 hexllo | 菜鸟二级 | 园豆:318
提问于:2015-08-03 15:57
< >
分享
最佳答案
0

已解决,总结如下:必须满足2个条件,否则它不进入success:function(){}而是直接进入error函数

 
1,前台必须指定架设函数的名称,
但可以不用声明回调函数,直接在success:function(x){..}里对返回的数据处理
 
如下:
 function Test() {

            $.ajax({
                url: "http://api.com/commonAPI/JsonP?sessionID=fff",
                dataType: "jsonp",
                //自定义的jsonp回调函数名称"jsonpCallback",返回的json也必须有这个函数名称
                jsonpCallback: "OnCall",
                success: function (json) {
                    alert("OK");
                    alert(json);
                },
                error: function (xhr, status, error)
                {
                    alert("ER");
                    console.log(xhr);
                }
            });
        }
 
 
2,后台返回的字符串中必须包含前台所指定的回调函数的名称
 
至于返回的内容,除了要用回调函数括起来外,没有任何要求.返回什么数据都可以
 [HttpGet]
        public string JsonP(string sessionID)
        {
            //return "OnCall('as=882ffe,asdfo239')"; 
            return "OnCall(alert('FFF'))";
        }
hexllo | 菜鸟二级 |园豆:318 | 2015-08-04 16:39
其他回答(2)
0

Controller中的代码需要这么写:

public ActionResult JsonP(string sessionID, string callback)
{
    return JavaScript(string.Format("{0}('{1}')", callback, sessionID));
}
收获园豆:12
dudu | 园豆:31003 (高人七级) | 2015-08-03 16:16

谢谢你的回答,我试了一下,还是不能进入前端定义的回调函数或success:function(xx){...}

我后台的代码及跟踪如下图:

 

没有进入回调,后来我又在后台写死,如下图:

还是不进入回调,始终都是进error:function(xxx)...

我前端试了2种方式:

分别如下图:

到底是为什么不进入success或指定的回调函数呢?

 

对了,后台是为了测试才这样写的,以后还是要返回string,因为还有IOS ,Android也要调用..目前返回的都是json字符串,如果想跨域,我是不是必须要修改返回格式?那样其它平台调用后解析很麻烦..有什么好的解决思路吗?再次感谢du大

 

支持(0) 反对(0) hexllo | 园豆:318 (菜鸟二级) | 2015-08-04 15:11

@hexllo: 大侠,我搞定了.写了篇博客

请见:http://www.cnblogs.com/Hexllo/p/4702423.html

支持(0) 反对(0) hexllo | 园豆:318 (菜鸟二级) | 2015-08-04 16:40
0

跨域访问在客户端和服务端都可以完成,至于选择哪一种在于对于调用接口的拓展。

简单点像楼上圆友代码所示,注意返回的callback函数名称与请求地址的callback名称相同,详情可参考:http://www.jb51.net/article/21213.htm

至于服务端的实现方式对于你描述的可能没有必要,不必折腾…

收获园豆:8
Mr.Myr | 园豆:3 (初学一级) | 2015-08-03 18:10
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册