假设我们已经了解什么是同源策略,以及什么是浏览器的同源策略的限制。
现在我们需要在a.demo.com下的某个页面one.html 里加载不同域b.demo.com下的json数据。
我们都知道用<script>或者<img>标签的src属性是可以跨域从某个站点加载数据的,jsonp就是根据这个原理来实现。
我们同样也知道,当浏览器加载完<script>标签的内容之后,它会立即执行。所以为了不让浏览器报错,这些内容应该是一些变量的定义或者是函数的调用之类的东西。
但是,我们要使用这些数据,所以如果这些内容是变量的定义的话,那么我们将使用不了(你可以试下)。所以,我们要将这些数据包装在一个函数调用里面,让它作为这个函数调用的参数。
比如像下面这个样子:
jsonCallBack({"email":"123456789@qq.com"})
那么我们要在one.html里面怎么应用这个来自b.demo.com的数据呢?
讲完了理论,来实战。
首先,我们建立一个页面叫做jsonp-one.html,
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <button id="getData"> click me to get data</button> <script> window.onload = function(){ var btn = document.getElementById('getData'); var handle = function(){ var scriptEle = document.createElement('script'); scriptEle.src = 'http://localhost:8080/jsonData.json?callback=jsonCallBack'; document.getElementsByTagName('body')[0].appendChild(scriptEle); }; btn.addEventListener('click',handle,false); } var jsonCallBack = function(data){ console.dir(data); } </script> </body> </html>
我使用webstorm自带的浏览器查看功能,所以当我打开时,他的地址栏是这样的:http://localhost:63342/javascript/test/jsonp-one.html
主机地址是localhost,端口号63342。
可以看到,代码里当点击按钮的时候,会新建一个script标签,然后设置它的src为我们所需要的数据来源的地址,最后加上?callback=jsonCallBack 。这样子数据文件就可以被加载到。最后我们将这个script插入到body里面。
图为还未点击按钮之前的页面以及控制台。
然后我们新建一个文件,叫做jsonData.json,名字不重要,只要和jsonp-one.html里面的一致即可,重要的是里面的内容:
jsonCallBack({"email":"123456789@qq.com"})
这里的数据其实是调用一个函数,函数名jsonCallBack,参数是我们真正要传给jsonp-one.html页面的数据。
现在我们另起一个服务,正如上面的代码所示,
http://localhost:8080/jsonData.json?callback=jsonCallBack
通过这个地址可以访问到刚才jsonData.json的内容。图为jsonData.json的内容:
然后我们可以看到,在jsonp-one.html里面,我们定义一个函数jsonCallBack,这样的话,当我们加载完来自8080端口的数据时,便能够立即调用这个函数,因为这个函数我们在这里已经定义过了,所以不会报错,能够正常执行。至于我们要用这些数据来干什么,那就是你自己在jsonCallBack这个函数里面要做的事情了。
当我们点击按钮时,我们可以看到浏览器的network以及控制台的输出:
控制台:
可以看到,数据正确加载了。
就这样,实现了使用jsonp技术,将数据从端口8080的这个域,传到端口63342的这个域。