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