咱们将从这几个方面来分析jsonp跨域访问javascript
咱们先明白一个概念:同源策略
同源策略是一种浏览器的安全策略,一个脚本不能去执行另外一个和他不一样源的脚本内容。所谓同源指的是域名,协议,端口三个都要相同。因此当咱们经过js获取第三方的数据时(好比经过第三方API获取json数据),,浏览器是不容许咱们直接这样作的。因此咱们得使用一种技巧去访问不一样域,而后得到该域的数据。这个就是跨域访问。html
JSON: JavaScript Object Notation(JavaScript 对象表示法)经过名字咱们就大概能够知道是个啥了,json是一种轻量级的数据交换格式,而这个格式又是遵循的js的对象语法。因此我的认为json能够直接看作是js的一个子集。java
jsonp:json with padding 咱们来翻译一下就是:用来填充的json数据。咦?为何要这么叫呢。后面当咱们讲到jsonp的原理的时候,你就会知道这样取名字的缘由了(题外话:取名字真的是个技术活啊。每次遇到函数,变量比较多,如何取个好名字真的很重要)说人话就是:jsonp就是一种访问数据的非官方传输协议。node
经过前面咱们能够知道因为同源策略,咱们没法经过ajax直接去访问另外一个域名下的文件。那这时咱们怎么办,别急,直接不行,咱们间接还不行吗。咱们仔细想一想咱们的script标签,它是能够获取任何地方的文件的啊。咱们能够经过它来帮咱们获取咱们想要的东西。具体如何操做呢,咱们来看例子吧.ajax
首先咱们幻想一下咱们得到了数据以后咱们要干什么,咱们把获取的数据显示在页面上吧。
页面的htmljson
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>测试文件</title> </head> <body> <div> <h1>显示跨域访问得到的数据</h1> <div id="show"> </div> </div> </body> </html>
咱们再在页面中直接添加js函数来处理数据吧跨域
function show(data)//data参数就是咱们从另外一个域获取到的数据 { var node = document.getElementById('show'); p.innerHTML=p.innerHTML="这就是获取到的数据 "+data; }
咱们是直接把获取的数据显示出来浏览器
而后咱们如今去获取数据,咱们再添加一个节点,里面的src就是咱们要访问的第三方的url,只是在url后面咱们额外添加一个callback参数。安全
这是整个的代码服务器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>测试文件</title> </head> <body> <div> <h1>显示跨域访问得到的数据</h1> <div id="showdata"> </div> </div> <script type="text/javascript"> function show(data)//data参数就是咱们从另外一个域获取到的数据 { var node = document.getElementById('showdata'); p.innerHTML=p.innerHTML="这就是获取到的数据 "+data; } </script> <script type="text/javascript" src="url?callback=show"></script> </body> </html>
你们须要注意的是src="url?callback=show",咱们把以前定义的show函数做为callback参数传递给服务器端,这个函数就是一个回调函数,具体过程是这样:
一个前提是咱们使用jsonp是须要服务器端来配合的,咱们经过url访问到服务器的地址,而且传递了一个callback参数给服务器端,而后服务器端可以接收这个参数,而后将数据以json格式做为show函数的参数传递给它,也就是用json数据来填充这个show函数(如今明白叫jsonp的缘由了吧),而后调用这个函数,最后由于这个函数被执行,咱们的html中的div中就会显示出获取到的数据。
不过这样可能会显得死板,固定了何时调用。咱们能够动态生成一个script节点,这样咱们就能够在须要数据的时候动态调用了,这样就会更合理。我仍是上一下完整代码吧
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>测试文件</title> </head> <body> <div> <h1>显示跨域访问得到的数据</h1> <div id="showdata"> </div> </div> <script type="text/javascript"> //data参数就是咱们从另外一个域获取到的数据 function show(data) { var node = document.getElementById('showdata'); p.innerHTML=p.innerHTML="这就是获取到的数据 "+data; } function invokeRemoteData() { var node=document.createElement("script"); //remoteUrl就是第三方服务器的地址 var url=remoteUrl?callback=show ; node.setAttribute("src",url); var head=document.getElementsByTagName("head")[0]; //将建立的script节点添加到head的最后,调用开始 head.appendChild(node); } </script> </body> </html>
当咱们须要获取跨域数据时,直接调用invokeRemoteData函数,html页面中就会显示出获取到的数据。
ps: