代码之家  ›  专栏  ›  技术社区  ›  fred basset

jQuery get JSON响应为空

  •  3
  • fred basset  · 技术社区  · 15 年前

    我正在尝试使用一个简单的jQuery get JSON调用。我的成功处理程序非错误处理程序似乎都没有被调用。Firebug还将数据体显示为空。

    服务器是在web.py下运行的一段非常基本的代码。我已经通过lynx连接到服务器来测试了它,它可以下载json数据。

    以下是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"}
    
    
    3 回复  |  直到 15 年前
        1
  •  7
  •   Nick Craver    15 年前

    您不能使用XmlHttpRequest向另一个域(该规则包括一个不同的端口)发出请求,这被 same origin policy .

    结果 尝试 这样做是一个空的响应,所以您看不到内容。这只是出于安全目的而制定的规则…如果连接到同一主机和端口,则不存在问题。

        2
  •  1
  •   Patrick Chu    14 年前

    您可以在Apache中设置一个反向代理,使远程数据源看起来像来自本地域。我写了一篇关于如何做到这一点的博文:

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

        3
  •  0
  •   Francesco Casula    13 年前

    我找到了在跨域请求中获得空响应的错误回调的解决方法。

    在本例中,我使用的是Zepto,它是jQuery的一个轻量级版本,但我假设它在jQuery中也可以正常工作。

    首先,必须使用这些参数执行跨域请求:

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

    现在 $.ajax公司 函数内部使用 $.ajaxJSONP公司 对于跨域请求。这是原装的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/