2010-11-28 5 views
3

Я пытаюсь получить простой вызов jQuery, чтобы заставить JSON работать. Похоже, что мой обработчик обработчика ошибок не обрабатывается. Firebug также показывает тело данных как пустое.jQuery get JSON response is empty

Сервер - это очень простой бит кода, запущенный под web.py. Я протестировал сервер, подключившись к нему с помощью lynx, и он загружает данные json OK.

Вот JQuery:

 

$(document).ready(function() { 
    $.ajax({ 
     url: 'http://localhost:8080/settings.json', 
     cache: false, 
     success: function(json){ 
      alert('json success ' + json); 
     }, 
     error: function(xhr, textStatus, errorThrown) { 
      alert(xhr.statusText); 
     } 
    }); 
}); 

JSON data is: 
{"netmask": "255.255.0.0", "ipaddress": "192.168.1.153"} 
 

ответ

7

Вы не можете сделать запрос на другой домен (это правило включает в себя другой порт) с XmlHttpRequest, это блокируется same origin policy.

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

+0

вы можете Убедитесь, что OP выполняет междоменный вызов. а также междоменный вызов обычно вызывает исключение. – anirvan 2010-11-28 17:46:17

1

Вы можете настроить обратный прокси-сервер в Apache, который заставит удаленный источник данных выглядеть так, как будто он поступает из локального домена. Я написал в блоге о том, как это сделать:

http://senchabits.wordpress.com/2012/09/17/problem-accessing-json-data-from-a-local-data-source-is-not-permitted/

0

Я нашел обходной путь, чтобы получить обратный вызов ошибки с пустым ответом на просьбах Междоменных.

В этом примере я использую Zepto, облегченную версию jQuery, но я предполагаю, что это отлично работает и в jQuery.

Прежде всего, вы должны использовать эти параметры, чтобы сделать запрос Междоменного

$.ajax({ 
    url: url, 
    type: 'GET', 
    dataType: 'jsonp', 
    contentType: 'application/x-javascript', 
    crossDomain: true, 
    success: function (data, status) { /* ... */ } 
    error: function() { /* ... */ } 
    // ... 

Теперь $ .ajax функции внутренне использовать $ .ajaxJSONP для crossdomain запросов. Это оригинальный Zepto $ .ajaxJSONP функция:

$.ajaxJSONP = function(options){ 
    var callbackName = 'jsonp' + (++jsonpID), 
     script = document.createElement('script'), 
     abort = function(){ 
     $(script).remove() 
     if (callbackName in window) window[callbackName] = empty 
     ajaxComplete('abort', xhr, options) 
     }, 
     xhr = { abort: abort }, abortTimeout 

    if (options.error) script.onerror = function() { 
     xhr.abort() 
     options.error() 
    } 

    window[callbackName] = function(data){ 
     clearTimeout(abortTimeout) 
     $(script).remove() 
     delete window[callbackName] 
     ajaxSuccess(data, xhr, options) 
    } 

    serializeData(options) 
    script.src = options.url.replace(/=\?/, '=' + callbackName) 
    $('head').append(script) 

    if (options.timeout > 0) abortTimeout = setTimeout(function(){ 
     xhr.abort() 
     ajaxComplete('timeout', xhr, options) 
     }, options.timeout) 

    return xhr 
    } 

Мой обходной путь очень прост и состоит на интервал называется несколько раз на обработчик события script.onload для того, чтобы убедиться в том, что функция обратного вызова назывались ,

Это моя версия функции $ .ajaxJSONP:

$.ajaxJSONP = function(options){ 
    var called = false, // Flag to check that callback was called 
     callbackName = 'jsonp' + (++jsonpID), 
     script = document.createElement('script'), 
     abort = function(){ 
      $(script).remove() 
      if (callbackName in window) window[callbackName] = empty 
      ajaxComplete('abort', xhr, options) 
     }, 
     xhr = { abort: abort }, abortTimeout 

    if (options.error) { 
     script.onerror = function() { 
      xhr.abort() 
      options.error() 
     }; 

     // IMPORTANT!!! 
     script.onload = function() { 
      var times = 0; 

      var interval = setInterval(function() { 
       // After 5 intervals, if the callback wasn't called, returns an error 
       if (times++ == 5) { 
        clearInterval(interval); 

        if (!called) { 
         options.error(); 
        } 
       } else if (called) { 
        clearInterval(interval); 
       } 
      }, 100); 
     }; 
    } 

    window[callbackName] = function(data){ 
     // Setting the "called" flag to true 
     called = true; 
     clearTimeout(abortTimeout) 
     $(script).remove() 
     delete window[callbackName] 
     ajaxSuccess(data, xhr, options) 
    } 

    serializeData(options) 
    script.src = options.url.replace(/=\?/, '=' + callbackName) 
    $('head').append(script) 

    if (options.timeout > 0) abortTimeout = setTimeout(function(){ 
     xhr.abort() 
     ajaxComplete('timeout', xhr, options) 
    }, options.timeout) 

    return xhr 
} 

Примечание: Если вы заинтересованы в поведении на стороне сервера, пожалуйста, см начало этого урока: http://phonegap.com/2011/07/20/making-jsonp-calls-with-zepto-on-android-device/