在this John Resig article中,他正在使用javascript处理字典大小的单词列表,并且他正在通过CD中的ajax加载内容。
这些单词加载了分隔单词的换行符。然后他说跨域失败:
但是有一个问题:我们无法从CDN加载我们的字典! 由于CDN位于另一个服务器上(或另一个子域, 就像这里的情况一样)我们受浏览器的交叉起源的支配 政策禁止这些类型的请求。一切都没有丢失 - 通过对字典文件的简单调整,我们可以加载它 域。
首先,我们用空格替换字典文件中的所有结束行。 其次,我们用JSONP语句包装整行。因此最终 结果看起来像这样:
dictLoaded('aah aahed aas aahs aals ... zyzzyvas zzz');
这允许我们对文件执行Ajax请求并使其工作 期望它 - 虽然仍然受益于所有的缓存和 浏览器提供的压缩。
因此,如果我正确地阅读此内容,只需在原始内容周围添加方法dictLoaded('original content')
就会导致ajax请求失败。
那是(把它变成一个函数+参数)真的需要它吗?为什么JSONP解决了跨域访问限制的问题?
答案 0 :(得分:6)
<script>
标记可以从任何地方(甚至是跨域)加载任何JS文件。随之而来的好处是该脚本中的代码也被执行,因此,这是一种绕过跨域限制的方法。
问题是,当代码执行时,它在全局范围内执行。所以有这个代码:
var test = 'foo'
将在全局范围内创建test
变量。
要缓解此问题,请使用函数中的回复。这是“JSONP”中的“P”,意思是“填充”。这将函数调用中包含您的回复。
所以如果你的外国脚本有:
myFunction({
test : 'foo'
});
它调用myFunction
并传递一个带有test
键的对象,其值为foo
。接收功能如下:
function myFunction(data){
//"data.test" is "foo"
}
现在我们已成功绕过跨域限制。所需的基本部分是:
答案 1 :(得分:3)
这是因为他补充了JSONP声明。
“带填充的JSON”是对基本JSON数据格式的补充。它提供了一种从不同域中的服务器请求数据的方法,这是典型Web浏览器因同源策略而禁止的。
这可以通过脚本元素注入来实现。
JSONP仅在与脚本元素一起使用时才有意义。对于每个新的JSONP请求,浏览器必须添加新元素,或重用现有元素。前一个选项 - 添加一个新的脚本元素 - 是通过动态DOM操作完成的,称为脚本元素注入。该元素被注入到HTML DOM中,并将所需JSONP端点的URL设置为“src”属性。这个动态脚本元素注入通常由javascript助手库完成。 jQuery和其他框架都有jsonp辅助函数;还有独立选项。
答案 2 :(得分:3)
那是(把它变成一个函数+参数)真的需要它吗?
是
为什么这会解决跨域访问限制的问题?
您应该阅读JSONP。我们的想法是,您现在可以包含动态指向资源的<script>
标记,而不是发送AJAX请求(禁止)。由于您已使用函数名称包装内容,因此将执行此函数并将其作为JSON对象的参数传递。所以剩下的就是定义这个功能。