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触发的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 在 Android 2.2.2 上的浏览​​器未获取 JSONP

JSONP 的 getJSON 回调有啥意义?

JSONP 不能使用来自 API 的结果

JSONP 回调方法未定义

使用 Ajax/jsonp 从 Web Api 接收数据

使用jquery jsonp返回错误回调函数没有被调用