为什么这个跨域请求解决方法有效?

Kri*_*ian 2 javascript ajax jsonp cross-domain

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

这些单词加载了分隔单词的换行符.然后他说跨域失败:

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

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

dictLoaded('aah aahed aahing aas aals ay ... zyzzyvas zzz');

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

所以,如果我正确地阅读这个,只是简单地dictLoaded('original content')在原始内容周围添加他的方法会导致ajax请求不会失败.

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

Jos*_*eph 6

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

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

var test = 'foo'
Run Code Online (Sandbox Code Playgroud)

test在全局范围内创建变量.

要缓解这种情况,请使用函数中的回复.这是"JSONP"中的"P",意思是"填充".这将在函数调用中包含您的回复.

所以如果你的外国脚本有:

myFunction({
    test : 'foo'
});
Run Code Online (Sandbox Code Playgroud)

myFunction使用test具有值的键调用并传递对象foo.接收功能如下:

function myFunction(data){
    //"data.test" is "foo"
}
Run Code Online (Sandbox Code Playgroud)

现在我们已成功绕过跨域限制.所需的基本部分是:

  • 接收功能(可以在使用后动态创建和丢弃)
  • "填充"JSON回复