jQuery getJSON 在本地工作,但不能跨域

标签 jquery json cross-domain jsonp getjson

我已经搜索了很久,但无法为我的问题找到明确的答案。所以就是这样。我有一个 JSON 文件(我去 jsonlint 进行验证,它说它很好),看起来像这样(修改了一些信息):

[{
        "position":"1",
        "category":"A",
        "title":"Title to first story",
        "description":"The first story."
    },
    {
        "position":"2",
        "category":"B",
        "title":"Title to second story",
        "description":"The second story"
    },
    {
        "position":"3",
        "category":"B",
        "title":"Title to third story",
        "description":"The third story"
    }
]

我使用 jQuery 来解析并使用此函数放置一个 html 页面:

$.getJSON('page.json', function(data) {
  var items = [];

  $.each(data.reponse, function(item, i) {
    items.push('<li id="' + i.position + '">' + i.title + ' - ' + i.description + '</li>');
  });

  $('<ul/>', {
    'class': 'my-new-list',
    html: items.join('')
  }).appendTo('body');
});

效果非常好!现在我的问题来了,JSON 文件不会托管在本地,实际上会托管在一个单独的域上。所以我修改了我的代码如下(经过一些阅读)希望能够让它工作:

$.getJSON('http://www.otherdomain.com/page.json?format=json&callback=?', function(data) {
  var items = [];

  $.each(data.reponse, function(item, i) {
    items.push('<li id="' + i.position + '">' + i.title + ' - ' + i.description + '</li>');
  });

  $('<ul/>', {
    'class': 'my-new-list',
    html: items.join('')
  }).appendTo('body');
});

通过添加“回调”行,我不再收到“无法加载资源”错误。然而,什么也没有发生。就好像我添加的功能根本不存在一样。我试图将其全部取出并添加一个简单的“警报(数据)”,但这甚至没有触发。我究竟做错了什么?一个大问题是我 100% 只能使用 HTML 和 JavaScript 来工作(不是我的选择)。感谢您的帮助!

编辑 好的,我无法让其他服务器动态地将任何内容添加到 json 文件中。所以我通过硬编码围绕 json 的函数进行修改(较小的示例):

storyData(
[{
        "position":"1",
        "category":"A",
        "title":"Title to first story",
        "description":"The first story."
    }
])

现在一切正常了!感谢您的帮助!

最佳答案

您需要查看 JSONP .

本质上,当您尝试从另一个域加载 JSON 时,它会失败,因为存在您无法跨越的域边界。为了避免这种情况,您必须PAD它(JSONP 中的 P)。填充它本质上是将其包装在函数调用中(函数名称驻留在您的客户端上)。 “正常”JSON 响应(例如 getjson.php):

{foo:'bar'}

带有 parseJSON 回调的 JSON 变为(例如 getjson.php?callback=parseJSON):

parseJSON({foo:'bar'})

请注意 callback 中提供的值如何成为您的 JSON 响应现在包装的函数的名称。

然后您的客户端将希望将其传递给 parseJSON,这是您客户端上存在的一个函数(您已定义)。 jQuery(和其他库)尝试通过生成一些“随机”函数,然后通过原始回调发送回响应(所有这些都是在幕后完成的)来为您解决这个问题。

如果您可以控制生成 JSON 的服务器页面,请实现一个回调方法,以便您可以提供 JSON 的包装方式,以便您可以在您的终端上使用它。 (仅当您处理来自客户端当前所在页面以外的域的数据时,才需要这样做)。

<小时/>

更新

要从根本上解决您遇到的问题,您需要找到一种方法将 JSON 信息放入 JSONP 调用中。在不知道“page.json”使用哪种语言的情况下,以下是它应包含的伪代码逻辑:

if GET_VARIABLE("callback") is supplied

  print GET_VARIABLE("callback") and an open parenthesis
  print normal JSON data
  print closing parenthesis

else

  print normal JSON data

end if

如果您决定对函数名称进行硬编码,而不是允许它作为“回调”在 url 中提供,那么您需要记住它。对于下一个示例,假设我们将其命名为 MyJSONPCallback

现在,在您的客户端代码中,您可以继续使用:

$.ajax({
  url: 'http://anotherdomain.com/page.json?format=json',
  dataType: 'json',
  jsonpCallback: 'MyJSONPCallback', // specify the callback name if you're hard-coding it
  success: function(data){
    // we make a successful JSONP call!
  }
});

关于jQuery getJSON 在本地工作,但不能跨域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6849802/

相关文章:

javascript - 如何在单元测试中调用 $(document).ready(function() {})

javascript - 在 Python 2.7 中使用 json.loads 返回 unicode 对象而不是 dict

javascript - Node.js 中的 CORS 问题失败

android - 如何在没有成员标签的情况下将 JsonElement 转换为 Json?

java - Geoserver 是否不允许跨域数据访问(getFeatureInfo)?

javascript - 为什么跨域 AJAX 请求标记为 "security risk"?

php - 通过电子邮件发送在 HTML5 canvas 上创建的图像

jquery - 在 Jqgrid 中显示 Enum 描述而不是 Enum

javascript - 如何使用 jQuery 访问存储在数组中的元素?

ios - XCODE 中的 Json.Net 错误 - System.Reflection.Emit