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

时间:2012-05-07 16:22:39

标签: javascript ajax cross-domain jsonp

this John Resig article中,他正在使用javascript处理字典大小的单词列表,并且他正在通过CD中的ajax加载内容。

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

  

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

     

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

     

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

     

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

因此,如果我正确地阅读此内容,只需在原始内容周围添加方法dictLoaded('original content')就会导致ajax请求失败。

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

3 个答案:

答案 0 :(得分:6)

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

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

var test = 'foo'

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

要缓解此问题,请使用函数中的回复。这是“JSONP”中的“P”,意思是“填充”。这将函数调用中包含您的回复。

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

myFunction({
    test : 'foo'
});

它调用myFunction并传递一个带有test键的对象,其值为foo。接收功能如下:

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

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

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

答案 1 :(得分:3)

这是因为他补充了JSONP声明。

  

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

这可以通过脚本元素注入来实现。

  

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

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

答案 2 :(得分:3)

  

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

  

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

您应该阅读JSONP。我们的想法是,您现在可以包含动态指向资源的<script>标记,而不是发送AJAX请求(禁止)。由于您已使用函数名称包装内容,因此将执行此函数并将其作为JSON对象的参数传递。所以剩下的就是定义这个功能。