【问题标题】:How to get JSON or JSONP results cross-origin from the visistat.com API using Ajax?如何使用 Ajax 从 visistat.com API 跨域获取 JSON 或 JSONP 结果?
【发布时间】:2012-08-22 20:38:58
【问题描述】:

我在 jQuery 中使用以下 API 调用来检索数据。我在末尾附加了?callback=?,这似乎解决了跨域域问题,如果我不包括我得到跨域错误。

在 chrome 中它说,“资源被解释为脚本,但使用 MIME 类型text/html 传输。”

返回的响应是Content-Type: text/html; charset=UTF-8

我可以通过在 Chrome ConsoleResources 中查看响应来查看响应。但是如何在 JavaScript 中操作响应?

$.getJSON("http://api.visistat.com/stats-api-v2.php?key=skx79q0pyu01.&qt=idd&d=json&sdate=2012-08-26&edate=2012-08-28?callback=?", function(json) {
    console.log(json);
});

我无权更改 API。

更新: 尝试使用 YQL 例如http://jsfiddle.net/4VEHR/5/

看起来这个插件也可能有用:https://github.com/padolsey/jQuery-Plugins/tree/master/cross-domain-ajax/

【问题讨论】:

  • 那个 API 链接对我不起作用。我认为它有某种 cookie,它会检查以验证您是否可以查看它。但是尝试使用YQL 作为代理 - 它可以读取 JSON 并返回 JSONP 或 CORS。
  • 抱歉,该页面的直接链接不起作用,要查看它转到网站,然后单击“现场演示”,然后单击“statcaster API”。感谢 YQL 的建议,我想我在这里取得了一些进展 goo.gl/6k5Tg
  • 我没有找到任何关于他们 API 的文档。 d 参数除了JSON 还能取什么值?我尝试了XML 或只是将其排除在外,但出现了各种错误。 YQL 的一个怪癖是,虽然它可以输入和输出 JSON,但在内部一切都是 XML,格式之间的转换会让它们有点“奇怪”。或许你可以使用d参数通过YQL得到更直接的数据格式。
  • 啊哈,我找到了文档。请注意,您可以选择其他输出格式,所有平面文本文件都使用各种分隔符,逗号是最常见的CSV 格式:select * from csv where url="http://api.visistat.com/stats-api-v2.php?key=skx79q0pyu01.&qt=idd&d=comma&sdate=2012-08-26&edate=2012-08-28" - 请注意,在某些格式中,一个字段具有奇怪的值 <?=$e?>,而在另一种格式。这可能是一个错误或一些您需要解决的怪癖?
  • 感谢以 CSV 格式提取数据,帮助我以更好的格式处理它。是的,有时数据看起来有点奇怪。

标签: jquery ajax json cross-domain asp.net-web-api


【解决方案1】:

像这样使用 $.ajax

$.ajax({
    url:"http://api.visistat.com/stats-api-v2.php?key=skx79q0pyu01.&qt=idd&d=json&sdate=2012-08-26&edate=2012-08-28",
    dataType:'jsonp',
    crossDomain:true,
    success:function(data){alert(data);}
})​;​

【讨论】:

  • 由于跨域限制而无法使用。似乎没有办法仅使用 Javascript 来使用该 API。
  • 仍然没有解决问题。服务器需要发送正确的标头。 (Access-Control-Allow-Origin) $.getJson 只是 $.ajax 的缩写,有一些配置但做同样的事情。
  • 这里有一个 fiddle 不工作(就像我说的。由于缺少标题,它不能工作)
【解决方案2】:

如果你使用 callback 参数,你告诉 jquery 使用 jsonP

这意味着您的回复应包含:

callback( ...your data...);

JSONP 意味着它创建了一个方法callback(可以获取数据)。比添加一个带有 src 属性的脚本标签你的 url。脚本被加载执行的回调方法。你有数据。

如果您无法访问/更改 api 来解决此问题,则无法使用 jsonP。

你说的是 CORS。这是一个不同的故事......你只需要确保它发送正确的标题。

http://enable-cors.org/

基本上确保它发送Access-Control-Allow-Origin: your domain (或 * 允许所有)

如果您不能这样做,您唯一的选择就是代理。代理是一种中间件。您向脚本发出请求,脚本获取数据并将其返回给您。例如php proxy。你可以在 asp、jsp、flash 甚至 java applet 中做同样的事情。

【讨论】:

  • 感谢您的回答,我想我需要进一步研究使用代理。我正在以 text/html 形式取回数据,所以认为必须有某种方法来操作它,但听起来这是不可能的。
  • text/html 是你的问题中最少的 :) 无论如何你都可以在你的代理中修改它们。
  • 尝试使用 YQL 解决此问题,请参见此处,我认为这现在是有效的 JSONP? goo.gl/6k5Tg
  • 是的,可以工作。您可以将诊断设置为 false(不需要),如果您调整查询,您可能可以使输出更好一些(更少的 json json json),但这已经可以工作了。
【解决方案3】:

除非您可以控制 api.visistat.com 并且可以修改 stats-api-v2.php 脚本,否则除了联系服务并要求他们修复他们发送的响应头(它需要 Content-Type: text/json,而PHP 默认为text/html)。在浏览器方面,您收到的警告发生在 Javascript 有机会处理数据之前 - jQuery 以您的 API URL 作为其源实例化一个 <script> 元素,并且浏览器在响应时立即注意到内容类型不匹配收到,然后将其传递回 jQuery。

不过,这个警告是无害的。真正的问题是您使用的服务不支持 JSONP——您提供了 jQuery 文档中指定的 callback 参数来强制 JSONP 结果预期,但该服务实际上并没有产生有效的 JSONP(它仍然产生纯 JSON )。我已经尝试在您的 API 请求中将 d=json 更改为 d=jsonp,但显然该服务不支持它。您需要想办法从服务中获取 JSONP 结果,或者在您的域上实现服务器端代理,以避免跨域问题。

【讨论】:

  • 这是有道理的,尽管我不明白为什么鉴于浏览器正在接收数据,通过一些变通方法无法处理文本/html 响应。如果我在服务器端实现某些东西,我在尝试使用 javascript 操作返回的文本/html 数据时是否仍会遇到同样的问题?我想这个想法是首先将其解析为 jsonp 之类的。 api页面的链接是visistat.com/tracking/api-manager.php
  • 如果您无法更改 api,服务器端代理是唯一的选择。在这种情况下,您可以发送任何您想要的响应标头...
  • 谢谢,我会尝试使用节点。
  • 您得到了一个有效的 JSON 响应,但带有错误的 Content-Type: text/html 标头。错误的标头 不是 这里的问题 — 问题在于您收到的 JSON 响应仅适用于同源内容。您正在发出跨域请求,因此您需要 JSONP 而不是 JSON,您使用的服务显然不支持 JSONP。即使您以某种方式解决了您收到的错误Content-Type,这根本不会改变这种情况,因为您仍然会收到 JSON 数据而不是 JSONP。
  • 感谢您的澄清。我在使用 YQL 方面取得了一些进展。我相信这是现在的 JSONP?我只需要在我的代码中整理回调?看这里goo.gl/6k5Tg
猜你喜欢
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
  • 2013-06-23
  • 2015-03-23
  • 2013-04-04
  • 2013-10-29
  • 1970-01-01
相关资源
最近更新 更多