返回 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 -> 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() 方法将此函数转换为文本并解析“/*
”和“*/
”之间的文本使用 JSONP 的 callback 函数,适用于所有旧浏览器。示例 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的主要内容,如果未能解决你的问题,请参考以下文章