【问题标题】:Return String from Cross-domain AJAX Request从跨域 AJAX 请求返回字符串
【发布时间】:2011-06-17 03:54:33
【问题描述】:

我正在寻找一种从跨域“AJAX”请求中返回单个 JSON/JSONP 字符串的方法。我不想请求字符串并让 JQuery 自动将其作为通用对象返回,而是希望在转换发生之前保留字符串。这里的目标是自己解析它,这样我就可以将它直接转化为某种类型的新对象(例如 Person 对象)。

所以,为了清楚起见,我不希望在幕后进行任何字符串到通用对象的转换,这必须使用不同的域。

这是我想做的一个非工作示例:

$.ajax({
    type: 'GET',
    url: 'http://www.someOtherDomain.com/GetPerson',
    dataType: 'text',
    success: parseToPerson
});

function parseToPerson( textToParse ) {
    // I think I can do this part, I just want to get it working up to this point
}

如果 JQuery 不参与解决方案,我非常高兴,只要它有效。不过,我更喜欢使用 JQuery。根据我的阅读,用于获取 JSONP 数据(动态创建脚本元素)的 javascript 技术可能会起作用,但我似乎无法让它为我工作。我控制我从中请求数据的域,如果我将 AJAX 调用中的 dataType 更改为“JSONP”,我可以获取数据,所以我知道这是有效的。

【问题讨论】:

  • 我设法让 JSONP“请求”在不使用 JQuery 的情况下工作。该方法包括添加一个脚本标签,其中 src 指向发回数据的 url。除非我使用 type="application/x-javascript",否则它对我不起作用。这会立即运行它,因此在我可以对其进行任何操作之前,将数据创建为通用对象。

标签: javascript jquery ajax jsonp


【解决方案1】:

如果您的数据是从另一个域检索的,您将需要使用 JSONP(还有其他选项,但如果您控制服务,JSONP 是迄今为止最简单的)。 jQuery 调用将如下所示:

$.ajax({
    // type: 'GET', --> this is the default, you don't need this line
    url: 'http://www.someOtherDomain.com/GetPerson',
    dataType: 'jsonp',
    success: parseToPerson
});

发送到您的服务的实际请求将是http://www.someOtherDomain.com/GetPerson?callback=arbitrary_function_name。在服务端,您需要返回如下数据:

arbitrary_function_name("the string (or JSON data) that I want to return");

因此,您需要检查查询字符串参数,获取 callback 参数的值,然后将其回显,就好像您正在调用具有该名称(您是)的 Javascript 函数,传入值您想通过服务提供。然后,您的 success 函数将使用您的服务提供的数据进行调用。

如果您要将返回的数据反序列化为 Javascript 对象,则返回 JSON 数据可能比返回字符串更好,因此您的服务返回的数据可能如下所示:

arbitrary_function_name({
    "name":"Bob Person", 
    "age":27, 
    "etc":"More data"
});

这样您就不必担心解析字符串 - 它已经存在于一个易于用于初始化您的对象的 Javascript 对象中。

【讨论】:

  • 那么,您是说我可以将服务中的数据序列化为 JSON 字符串,然后进一步将其包装为 JSONP 格式?我猜当它来到客户端时,它会将 JSON 字符串提供给回调函数。这不是一个坏主意。我想我也可以选择发送一个非 JSON 字符串,这可能允许我在回调函数中使用 eval 来创建新的 Person 对象。我认为这在客户端的速度和内存使用方面都是更有效的解决方案。我想你已经找到了我的答案,我的朋友,谢谢。
  • @BDawg - 当您使用 JSONP 时,您实际上是在运行您的服务返回的代码。所以你不需要使用eval——当你的服务吐出callback({"some":"data"});时,success函数实际上是在接收一个Javascript对象。因此,理论上,您可以返回成熟的 Person 对象 - 但您可以通过返回数据并在客户端实例化人员来更好地分离关注点。
  • @nrabinowitz - 啊,那不是你的意思。好吧,无论如何,我找到了答案。在这种情况下,JSONP 代码将向回调函数提供一个包含 Javascript 代码的字符串,而不是一个对象。因此,该服务会吐出更像这样的内容:callback("[new Person(\"John\":\"Doe\")]"); 我不确定这是否被认为是一种不好的做法,但它确实回答了我关于它如何可能的问题。
  • @BDawg - 好吧,如果你想那样做,你可以很容易地让服务代码制作类似callback(new Person("John", "Doe")) 的东西 - 序列化和反序列化字符串的额外步骤是不必要的。但这使得服务与客户端代码真正紧密耦合 - 让服务提供数据并让客户端代码创建对象要干净得多。
  • @nrabinowitz - 啊,好点子。我不需要以这种方式将它作为字符串发送到回调。您如何看待将其作为典型的 JSON 字符串发送并使用正则表达式插入“新人”、重新排序属性(以防万一)然后删除属性名称?我认为,这仍然会减少使用通用对象,并避免使服务和客户端耦合过于紧密。它会在内存上更快和/或更轻,还是只是一个不必要的步骤?
【解决方案2】:

不确定这将如何与 jsonp 结合使用,但也许 converters 是您正在寻找的?

$.ajax(url, {
  dataType: "person",
  converters: {
    "text person": function(textValue) {
      return parseToPerson(textValue);
    }
  }
});

【讨论】:

  • 试过了,JQuery 正在尝试使用 XMLHttpRequest 来获取数据。不幸的是,这不适用于来自另一个域的数据。不过谢谢。还有其他想法吗?
猜你喜欢
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2014-07-18
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多