【问题标题】:How to prevent getJSON or similar ajax request from parsing to JSON如何防止getJSON或类似的ajax请求解析为JSON
【发布时间】:2015-12-10 16:44:52
【问题描述】:

我在帮助 SO 的另一个用户时偶然发现了这个问题, 有一个发送 json 格式输出的 web 服务,当查看控制台时似乎没问题,但是当直接使用 getJSON 或类似的 ajax 请求解析它时会触发解析错误:

Unexpected token ':'. Parse error.

虽然这很奇怪,但可以通过获取纯文本来解决,但是服务器需要 JSONP 请求(它没有 CORS 标头)。 我尝试了多种方法来阻止 jQuery 自动解析对 JSON 的响应,但无济于事。如果有人知道如何修复看似不正确的解析错误或首先阻止解析,请告诉我。

到目前为止我尝试过的代码是:

var baseUrl = "https://acs.leagueoflegends.com/v1/stats/game/TRLH3/1001440043/timeline?gameHash=4725b07311676885&callback=?";

$.ajax({

  url: baseUrl,
  dataType: 'json',
  crossDomain: true,
  processData: false,

  converters: {"* text": window.String, "text html": true, "text json": true, "text xml": jQuery.parseXML},
  success: function(data){

    $('#output').html(data);
  },
  error:function(jqXHR,status, error){
    console.log(jqXHR);
    console.log(status);
    console.log(error);
    $('#output').html(jqXHR);
  }
});

Jsfiddle:https://jsfiddle.net/6Lwjpjmo/22/

为了让问题更清楚:
当我在 url 中使用带有回调的数据类型 json 或数据类型 jsonp 时,我可以在控制台中看到返回的 json 响应。但它会触发解析错误。
相反,如果我使用数据类型 text 或其他任何内容,则会收到跨域拒绝错误。

【问题讨论】:

  • 如果需要 JSONP,可能想将您的 dataType 更改为 jsonp。
  • 也试过了。没关系,在字符串中附加回调的数据类型 json 或在字符串中没有回调的 jsonp 的工作方式相同。
  • 另外我可以在 js 控制台中看到该请求返回了适当的内容,它只是不解析..

标签: javascript jquery json ajax


【解决方案1】:

将dataType 更改为文本。应该把它作为一个字符串让你用它做你喜欢的事情

var baseUrl = "https://acs.leagueoflegends.com/v1/stats/game/TRLH3/1001440043/timeline?gameHash=4725b07311676885&callback=?";

$.ajax({

  url: baseUrl,
  dataType: 'text',
  crossDomain: true,
  processData: false,

  converters: {"* text": window.String, "text html": true, "text json": true, "text xml": jQuery.parseXML},
  success: function(data){

    $('#output').html(data);
  },
  error:function(jqXHR,status, error){
    console.log(jqXHR);
    console.log(status);
    console.log(error);
    $('#output').html(jqXHR);
  }
});

【讨论】:

  • 不起作用..你自己检查了吗?它使用此设置给出访问源错误。我自己也试过了。
  • 我以前用过,没设置新实例检查一下。究竟是什么错误?当我听到来源错误时,我认为您必须明确允许跨域访问。
  • 这就是重点……使用 JSONP,您不需要跨域访问,这就是发明 jsonp 的原因。如果我将数据类型指定为 json 或 jsonp,它会给出响应但会触发解析错误。当不使用这些数据类型时,它会给出跨源访问被拒绝错误。你可以添加我的 jsfiddle 来自己玩。 (在资源控制台中查看请求是否使用 json 正确加载)
  • 啊,我应该再花一分钟。是的,跨域你是相当有限的。你可以参考这里的讨论:stackoverflow.com/questions/7157455/… 或者在返回值上使用 JSON.stringify()。这将导致一些开销。
  • Stringify 由于解析时崩溃而无法选择,也许代理服务器是唯一的方法..
【解决方案2】:

服务器没有返回 JSONP,这是问题的根源。您不能通过 callback=? 并假设服务器将包装响应(它需要成为架构的一部分)。

也就是说,您遇到了两个问题:

  1. 服务器未实现 CORS,因此禁止像在同一个域中一样访问数据(基于浏览器安全策略)。
  2. 服务器没有将响应包装在提供的回调中,因此 jQuery 没有使用其 jQuery_* 回调函数。

我不熟悉 API,但如果没有特定的方式来获取 JSONP 响应(有些是通过存在 callback 参数激活的,其他是通过请求 URI 等方式激活的)。 ),您在使用 JavaScript 远程检索数据时运气不佳(没有遇到跨域策略)。

--

详细说明:

支持 JSONP 的服务器在与 jQuery 一起使用时,将返回包含在回调中的响应。例如

GET http://server.com/endpoint?callback=Foo

结果如下:

Foo({json})

此服务仍然只是返回{json}(嗯,具体如下):

{"frames":[ ...snip... ],"frameInterval":60000}

这使得 JSONP 成为失败的选择。


使用通过快速 google (jsonp.afeld.me) 找到的代理服务的示例:

var proxyUrl = 'https://jsonp.afeld.me/';
var serviceUrl = "https://acs.leagueoflegends.com/v1/stats/game/TRLH3/1001440043/timeline?gameHash=4725b07311676885";

$.ajax({
  url: proxyUrl + '?url=' + encodeURIComponent(serviceUrl) + '&callback=?',
  dataType: 'jsonp'
}).done(function(data){
  // `data` is a JSO, so serialize it before placing in the #output
  // element (otherwise we'll just see `[object Object]`)
  $('#output').text(JSON.stringify(data, null, '  '));
});

【讨论】:

  • 感谢您的建议,可能如您所说。虽然浏览器在使用 jsonp 设置加载时确实下载了完整的响应,但这是相当奇怪的(不是说它可以在 js 中使用..)
  • 浏览器会获取响应,是的,但它不会知道它是否正确包装,直到它[本地]筛选/解析它(在移交给页面的脚本之前)。
  • @BasvanStein:看起来,通过快速的谷歌搜索,你可以使用一个代理(jsonp.afeld.me)。这是您的小提琴(成功)与它一起使用的示例:jsfiddle.net/6Lwjpjmo/25
猜你喜欢
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-23
  • 2015-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多