2010-03-04 2 views
28

Выполнение некоторых игр вызывает мой сервис, который находится в другом домене, используя jQuery. Вызов службы успешно выполнен (моя точка отладки отключена), и возвращается правильный ответ (я обнюхаю трафик).Функция успешной JQuery не срабатывает с использованием JSONP

Моя проблема в основном в том, что успешные и отказоустойчивые обратные вызовы не срабатывают. Я прочитал около other posts на SO, которые указывают, что событие ошибки не запускается при использовании 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....'); 
    } 
}); 
+0

Вы работали с этим в отладчике? После вызова вы можете узнать, добавила ли jQuery глобальную функцию с именем типа «jsonpNNN» (где NNN - это число)? – Pointy

+0

Да, jquery добавила глобальную функцию jsonPXXXX –

ответ

19

Хорошо. В случае, если кто-то должен знать в будущем ... Оглядываясь назад, решение, вероятно, должно было быть более очевидным, чем было, но вам нужно, чтобы веб-ответ записывался непосредственно в ответ поток. Простое возвращение строки 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 в целях безопасности - хотя я не много исследовал.

+0

Самый простой способ сделать службу JSONP в .NET - использовать HTTP-обработчик, тогда нет разметки страницы для подавления, вы просто пишете поток ответов. – Guffa

+0

Из любопытства: как вы «вернули» строку, когда вы не записали ее в поток ответов? – Guffa

+0

Согласен Guffa. Это также не помогает удалить стандартную оболочку JSON по умолчанию, которую предоставляет WCF. Вы можете обойти это, но это просто еще одна вещь, чтобы иметь в виду. A: По наивному обращению «материал»; –

0

Попробуйте

$.getJSON(urlOnDiffDomain, function(data, textStatus){ 
    alert('success...'); 
}); 

Работы для меня, Usally. Вам нужно добавить & callback =? на urlOnDiffDomain, где jQuery автоматически заменяет обратный вызов, используемый в JSONP.

обратного вызова ошибки не запускается, но вы можете использовать глобальную $ .ajaxError, как этот

$('.somenode').ajaxError(function(e, xhr, settings, exception) { 
    alert('failed'); 
}); 
+1

С возвращением строки так же, как я указал в своем первом комментарии выше..если я заканчиваю свой URL с & callback = ?, я получаю http 403. Если я заканчиваю ? callback = ?, я добираюсь до службы, однако мое успешное событие все еще не уволено: -? (JQuery создает функцию JSONPXXXX) –

13

Метод 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' 
}); 
+0

Я изменил значение, возвращенное из моей службы. Теперь он выглядит так: string qs = HttpContext.Current.Request.QueryString ["callback"]; return qs + "({'d': 's'})"; С учетом следующего клиентского кода: var url = 'http: //some.other.domain/service/serviceName.svc/param1/1/param2/2'; $ .ajax ({ URL: URL, DATATYPE: 'JSONP', данные: {}, jsonpCallback: 'mycallback', успех: функция (данные, textStatus) { оповещения (данные); } }) }) Содержание от ответа выглядит так: «jsonp1267721964115 ({'d': 's'})« Похоже, что он подключает функцию обратного вызова, несмотря на свойство? –

+0

Ugh. Извините, что форматирование –

+0

@rhythmaddict: Какую версию jQuery вы используете? Для использования свойства jsonpCallback вам потребуется версия 1.4 или новее. Однако, когда вы изменили код сервера, чтобы правильно использовать строку запроса обратного вызова, вам не нужно использовать свойство jsonpCallback. – Guffa

0

Это не полный ответ на ваш вопрос, но я думаю, что кто-то проходит мимо хотел бы знать это:

Когда вы имеете дело с JSONP from WCF REST пытаются использовать:

[JavascriptCallbackBehavior(UrlParameterName = "$callback")]

для реализация вашей услуги; это должно дать вам JSONP из коробки.

0
$.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); 
        } 
      }); 
+6

При отправке ответа не просто укажите код. Пожалуйста, объясните, что будет делать ваш код или как он отличается от примера оригинального плаката.Ответ будет работать лучше всего, если вы сможете объяснить его оригинальному плакату, чтобы они поняли, что он делает. –