返回 XML 时使用 JSONP

Posted

技术标签:

【中文标题】返回 XML 时使用 JSONP【英文标题】:Using JSONP when returning XML 【发布时间】:2011-03-27 00:20:23 【问题描述】:

我问过一个较早的question,这肯定很有帮助,并让我知道了 JSONP。但是,我看到我必须将 JSONP 指定为数据类型。现在,据我所知,这是返回数据的返回类型,即 XML。可以使用 JSONP 返回 XML,还是仅限于以 JSONP 格式返回?谢谢!

【问题讨论】:

【参考方案1】:

由于它的工作方式,您只能使用 JSONP(而不是 XML)。 JSONP变成了这样:

<script src="myPage?callback=myFunction" type="text/javscript">

因此,当您获取内容时,它有效地这样做了:

<script type="text/javascript">
  myFunction( data: value, data2: value2 );
</script>

返回的是实际运行的 JavaScript,所以它不可能是 XML,你会得到各种各样的语法错误,正是你会这样做:

<script type="text/javascript">
  <elem>
    <data>value</data>
    <data2>value2</data2>
  </elem>
</script>

您可以想象,JavaScript 解析器不会非常喜欢它,也不知道如何处理它。 jQuery 在大多数情况下可以毫无问题地解析 XML,但是如果您使用 JSONP 并且它用于跨域请求......那么 JSONP 是您唯一的选择,除非您在您的网站上编写了一个没有违反的代理页面同源策略规则,并将其用作代理来获取 XML。

【讨论】:

感谢您的帮助!如果我想将数据发布到 API而不 使用 JSONP,我可以将数据发布到 API,而不必担心奇怪的跨域内容对吗?感谢您的帮助,我是一个 php 人,Javascript/jQuery 对我来说仍然很新!基本上我正在尝试编写一个小部件以放在其他网站上,所以我仅限于 Javascript,并且不能使用任何服务器端。再次感谢! @patricksweeney - 您可以发布是,但您不会收到回复,这是 来自 服务器的响应,而不是 POST to 您的浏览器阻止的服务器...POST 响应的内容将为空,这就是同源安全在每个主要浏览器中的工作方式。 所以基本上我应该看看我们是否可以将服务器响应包装在 JSONP 中或使用代理,对吧? @patricksweeney - 正确,这是您最好的两个解决方案 :) 我正在尝试通过 json 获取 NexTrip API,但它返回了一个 XML 文件。我要疯了吗?【参考方案2】:

这个想法是从服务器发回可执行代码。编写一个 jQuery 插件或扩展 ajax 函数以将 XML 字符串作为函数参数返回。

myCallback("
  <root>
    <person>
      <first>John</first>
      <last>Doe</last>
    </person>
  </root>")

插件会将此字符串解析为 XML 并将其返回给您的实际回调。就您的回调而言,它不知道string -&gt; xml 转换过程。

这是一个现有的implementation。

jQuery 最理想的接口是,

$.ajax(
    url: 'http://example.com/resource?type=xml',
    dataType: 'xmlp',
    success: function(xml)  .. 
);

但由于搞乱和重写jQuery.ajax 是有问题的,你可以把它写成一个单独的命名空间插件本身,它将在下面使用getScript

$.myNamespace.ajax(
    ..
);

为此,您需要控制服务器。服务器必须知道请求了 XML,并以包含 XML 字符串作为参数的函数调用进行响应。假设您发送到远程服务器的回调名称是foo,服务器将必须响应如下内容:

foo("<names><name>..</name></names>")

我认为,如果您使用的是支持 E4X 的浏览器,则无需将 XML 包装在字符串中。服务器可以简单地将 XML 作为参数返回给回调函数:

foo(
  <names>
    <name>John Doe</name>
  </names>
)

但不幸的是,E4X 尚未得到广泛支持。

【讨论】:

如果将dataType 设置为jsonp xml,jQuery 确实支持xmlp。根据文档:“从 jQuery 1.5 开始,jQuery 可以将数据类型从它在 Content-Type 标头中收到的内容转换为您需要的内容。例如,如果您希望将文本响应视为 XML,请使用“文本 xml”对于数据类型。您还可以发出 JSONP 请求,将其作为文本接收,并由 jQuery 解释为 XML:“jsonp text xml”。类似地,诸如“jsonp xml”之类的速记字符串将首先尝试从 jsonp 转换为xml,如果失败,则从 jsonp 转换为文本,然后从文本转换为 xml。” @greg.kindel - 感谢您提供的信息。我会尝试更新答案,但我现在有点懒。【参考方案3】:

您可以在/* comment */ 内部的Javascript 函数中编写XML,并使用functionname.toString() 方法将此函数转换为文本并解析“/*”和“*/”之间的文本使用 JSONPcallback 函数,适用于所有旧浏览器。示例 xml_via_jsonp.js

function myfunc()
/*
<xml>
<div class="container">
        <div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel">
            <div class="panel-heading">Random1 - Random2</div>
            <div class="panel-body">
                <div>Random3</div>
            </div>
        </div>
    </div>
</xml>
*/

function callback(func)

var myhtml = func.toString();
var htmlstart = myhtml.indexOf('/*');
var htmlend = myhtml.lastIndexOf('*/');
return myhtml.substr(htmlstart+2, htmlend-htmlstart-2);

【讨论】:

这是个糟糕的主意。 你有什么更好的主意? 您可以简单地将 XML 存储在一个字符串中。用xml_string 完全跳过整个func.toString() 您必须在所有引号中添加斜杠,这会使 XML 难以阅读 好吧,理想情况下,你会生成你的 XML 服务器端,序列化它,编码成 JSON 字符串,返回给客户端,然后客户端反序列化 JSON 字符串,然后得到 XML 字符串.

以上是关于返回 XML 时使用 JSONP的主要内容,如果未能解决你的问题,请参考以下文章

php返回json,xml,JSONP等格式的数据

AJAX中的dataType

接口测试返回数据为JSONP格式时如何处理

使用AngularJS返回xml的跨域ajax请求

NodeJS 不使用 express 返回 JSONP

angularjs - 返回 JSONP 时不执行 HTTPpromise