2

这篇 John Resig 文章中,他正在使用 javascript 处理字典大小的单词列表,并且他正在通过 ajax 从 CDN 加载内容。

单词用分隔单词的换行符加载。然后他说跨域失败:

但是有一个问题:我们无法从 CDN 加载我们的字典!由于 CDN 位于另一个服务器上(或另一个子域,就像这里的情况一样),我们受制于浏览器禁止这些类型请求的跨域策略。一切都不会丢失 - 通过对字典文件进行简单的调整,我们可以跨域加载它。

首先,我们用空格替换字典文件中的所有结束行。其次,我们用 JSONP 语句包装整行。因此最终结果看起来像这样:

dictLoaded('aah aahed aahing aahs aal... zyzzyvas zzz');

这允许我们对文件执行 Ajax 请求并让它按预期工作 - 同时仍然受益于浏览器提供的所有缓存和压缩。

所以,如果我没看错的话,仅仅dictLoaded('original content')在原始内容周围添加他的方法就会导致 ajax 请求不会失败。

这(把它变成一个函数+参数)真的只需要吗?JSONP为什么能解决跨域访问限制的问题?

4

3 回答 3

6

标签可以从<script>任何地方(甚至跨域)加载任何 JS 文件。它带来的好处是该脚本中的代码也被执行,因此,这是一种绕过跨域限制的方法。

问题是,当代码被执行时,它是在全局范围内执行的。所以有这个代码:

var test = 'foo'

将在全局范围内创建一个test变量。

为了缓解这种情况,您可以将回复包含在一个函数中。这是“JSONP”中的“P”,意思是“填充”。这会将您的回复包含在函数调用中。

因此,如果您的外国脚本有:

myFunction({
    test : 'foo'
});

它使用具有 value 的 key调用myFunction并传递一个对象。接收函数如下所示:testfoo

function myFunction(data){
    //"data.test" is "foo"
}

现在我们已经成功绕过了跨域限制。所需的基本部件是:

  • 接收函数(使用后可以动态创建和丢弃)
  • “填充” JSON 回复
于 2012-05-07T16:27:45.877 回答
3

这是因为他添加了JSONP语句。

“带填充的 JSON”是对基本 JSON 数据格式的补充。它提供了一种从不同域中的服务器请求数据的方法,由于同源策略,典型的 Web 浏览器禁止这样做。

这通过脚本元素注入工作。

JSONP 仅在与脚本元素一起使用时才有意义。对于每个新的 JSONP 请求,浏览器必须添加一个新元素,或重用现有元素。前一个选项——添加一个新的脚本元素——是通过动态 DOM 操作完成的,被称​​为脚本元素注入。该元素被注入 HTML DOM,并将所需 JSONP 端点的 URL 设置为“src”属性。这种动态脚本元素注入通常由 javascript 帮助程序库完成。jQuery等框架有jsonp辅助功能;还有独立选项。

来源:http ://en.wikipedia.org/wiki/JSONP

于 2012-05-07T16:25:16.767 回答
3

这(把它变成一个函数+参数)真的只需要吗?

是的。

为什么这解决了跨域访问限制的问题?

您应该阅读有关JSONP的信息。这个想法是您现在可以包含一个<script>动态指向资源的标签,而不是发送 AJAX 请求(这是被禁止的)。由于你已经用函数名包装了内容,这个函数将被执行并作为参数传递给 JSON 对象。所以剩下的就是定义这个函数。

于 2012-05-07T16:25:23.677 回答