Jquery成功函数未使用JSONP触发
Posted
技术标签:
【中文标题】Jquery成功函数未使用JSONP触发【英文标题】:Jquery success function not firing using JSONP 【发布时间】:2011-01-23 17:53:38 【问题描述】:一直在使用 jQuery 调用我在不同域中的服务。成功调用服务(我的调试点被触发),并返回正确的响应(我嗅探流量)。
我的问题主要是成功和失败回调没有被触发。我在 SO 上阅读了一些other posts,表明使用 JSONP 时不会触发错误事件。是成功事件的情况(可能是因为假设我提供了自己的回调函数),还是有办法触发我的成功回调。提前致谢。
$.ajax(
type: "GET",
url: urlOnDiffDomain,
async: false,
cache: false,
dataType: 'jsonp',
data: ,
success: function(data, textStatus)
alert('success...');
,
error: function(xhr, ajaxOptions, thrownError)
alert('failed....');
);
【问题讨论】:
你在调试器中使用过这个吗?调用后,能否判断 jQuery 是否添加了一个名为“jsonpNNN”(其中 NNN 是数字)的全局函数? 是的,jquery添加了全局函数jsonPXXXX 【参考方案1】:好的。万一将来有人需要知道...事后看来,解决方案可能应该比以前更明显,但是您需要让网络响应直接写入响应流。简单地返回一串 JSON 是行不通的,您需要有人构造它并将其流回。如果您确实这样做,我原始帖子中的代码将可以正常工作。
服务代码示例:
public void DoWork()
//it will work without this, but just to be safe
HttpContext.Current.Response.ContentType = "application/json";
string qs = HttpContext.Current.Request.QueryString["callback"];
HttpContext.Current.Response.Write(qs + "( [ \"x\": 10, \"y\": 15] )");
为了明确起见,这是客户端代码。
function localDemo()
$.getJSON("http://someOtherDomain.com/Service1.svc/DoWork?callback=?",
function(data)
$.each(data, function(i,item)
alert(item.x);
);
);
如果有更好的方法可以做到这一点,我会全力以赴。对于其他所有人,我知道 WCF 4.0 中有一些原生支持 JSONP 的概念。此外,出于安全目的,您可能想要做一点checking - 尽管我没有进行太多调查。
【讨论】:
在 .NET 中创建 JSONP 服务的最简单方法是使用 HTTP 处理程序,然后没有要抑制的页面标记,您只需写入响应流。 出于好奇:当您没有将字符串写入响应流时,您是如何“返回”字符串的? 同意古法。删除 WCF 为您提供的默认 JSON 包装器也无济于事。您可以解决它,但这只是要记住的另一件事。 A:天真地做一个返回“东西”; 如果您使用回调包装 JSON 数据,我认为内容类型不是 application/json。我使用文本/javascript。 感谢帮助我的兄弟。【参考方案2】:服务器响应时调用success
回调方法。 $.ajax
方法设置一个函数,通过调用success
回调方法来处理响应。
success
方法未被调用的最可能原因是服务器的响应不正确。 $.ajax
方法在callback
查询字符串中发送一个值,服务器应将其用作 JSONP 响应中的函数名。如果服务器使用不同的名称,则永远不会调用 $.ajax
方法设置的函数。
如果服务器不能使用callback
查询字符串中的值来设置响应中的函数名称,您可以指定$.ajax
方法应该从服务器获得的函数名称。将属性jsonpCallback
添加到选项对象中,并将值设置为服务器在响应中使用的函数的名称。
例如,如果 $.ajax
方法使用 URL http://service.mydomain.com/getdata?callback=jsonp12345
向服务器发送请求,则服务器应以如下所示的内容进行响应:
jsonp12345(...);
如果服务器忽略了callback
查询字符串,而是以如下方式响应:
mycallback(...);
然后您必须通过向选项对象添加属性来覆盖函数名称:
$.ajax(
url: urlOnDiffDomain,
dataType: 'jsonp',
data: ,
success: function(data, textStatus)
alert('success...');
,
jsonpCallback: 'mycallback'
);
【讨论】:
我已经更改了从我的服务返回的值。现在看起来像这样: string qs = HttpContext.Current.Request.QueryString["callback"];返回 qs + "('d':'s')";给定以下客户端代码: var url = 'some.other.domain/service/serviceName.svc/param1/1/param2/2'; $.ajax( url: url, dataType: 'jsonp', data: , jsonpCallback: 'mycallback', success: function(data, textStatus) alert(data); ) 响应的内容看起来像: "jsonp1267721964115('d':'s')" 尽管有属性,似乎它附加了一个回调函数? @rhythmaddict:你使用的是什么版本的 jQuery?您需要 1.4 或更高版本才能使用 jsonpCallback 属性。但是,当您更改服务器代码以正确使用回调查询字符串时,您不需要使用 jsonpCallback 属性。【参考方案3】:试试
$.getJSON(urlOnDiffDomain, function(data, textStatus)
alert('success...');
);
通常对我有用。您需要添加 &callback=?到 urlOnDiffDomain,其中 jQuery 会自动替换 JSONP 中使用的回调。
不触发错误回调,但可以使用全局$.ajaxError,像这样
$('.somenode').ajaxError(function(e, xhr, settings, exception)
alert('failed');
);
【讨论】:
服务返回字符串的方式与我在上面的第一条评论中指出的方式相同。如果我以 &callback=? 结束我的 URL,我会得到一个 http 403。如果我以 ?callback= 结束?,我得到了服务,但是我的成功事件仍然没有被触发:-? (Jquery 确实创建了 JSONPXXXX 函数)【参考方案4】:这不是您问题的完整答案,但我认为路过的人想知道这一点:
当你处理JSONP from WCF REST时尝试使用:
[JavascriptCallbackBehavior(UrlParameterName = "$callback")]
为您的服务实施;这应该为您提供开箱即用的 JSONP。
【讨论】:
【参考方案5】: $.ajax(
url:' <?php echo URL::site('ajax/editing?action=artistSeracher') ?>',
dataType: "json",
data:
featureClass: "P",
style: "full",
maxRows: 12,
artist: request.term
,
success: function( data )
response( $.map( data, function( item )
return
label: item.artist,
value: item.artist,
id: item.id
));
,
error: function (xhr, ajaxOptions, thrownError)
alert(xhr.status);
alert(thrownError);
);
【讨论】:
发布答案时不要只提供代码。请解释您的代码将做什么或它与原始海报示例有何不同。如果您可以向原始发帖者解释,那么答案将最有效,以便他们了解它在做什么。以上是关于Jquery成功函数未使用JSONP触发的主要内容,如果未能解决你的问题,请参考以下文章