fengchao000 2020-03-05
一、什么是同源策略
同源策略:同源是指域名、协议、端口均相同
跨域:是指从一个域名的网页去请求另一个域名的资源,只要域名、协议、端口有一个不同,就被当作是跨域
JSONP是我们解决跨域最常用的方式
二、JSONP的原理
JSONP是JSON with Padding的简写,是一种跨域的解决方案
JSONP由两部分解组成:回调函数和数据。回调函数是当相应到来的时候,应该在页面中调用的函数,数据就是传回回调函数中的JSON数据
JSONP的原理:我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的,但是在用link标签和script标签引入其他域上的脚本文件是可以的,JSONP就是利用script标签上的src属性来加载不同域上的资源
JSONP重要的一点就是允许用户传递一个函数名作为参数传给服务端,然后服务端返回数据时,会将这个函数参数作为函数名来来包裹住数据,函数名(数据),这样客户端就可以随意定制自己的函数来自动处理返回数据了;例如我们传给服务端的函数名是abc,那么服务器端就会将我们所需要的数据作为abc函数的参数返回来abc(数据),服务端返回的数据是JSON格式的,这也是JSONP封装的思路
三、封装JSONP函数
function getJSONP(url,callback){ if (!url) { return; } else { // 声明数组用来随机生成函数名,索引 var a=[‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘,‘g‘,‘h‘,‘i‘,‘j‘], r1=Math.floor(Math.random()*10), //Math.floor()取整函数,这样r1,r2,r3就是随机的0-9 r2=Math.floor(Math.random()*10), r3=Math.floor(Math.random()*10), name=‘JSONP‘+a[r1]+a[r2]+a[r3]; cbname=‘getJSONP.‘+name; //随机生成的函数名要作为getJSONP的一个属性,方便后面删除delete getJSONP[name]; // console.log(cbname); if(url.indexOf(‘?‘)===-1){ url+=‘?jsonp=‘+cbname; }else{ url+=‘&jsonp=‘+cbname; } // console.log(url); // 动态创建script标签,第1步,通过src引入js文件, var script=document.createElement("script"); script.src=url; document.getElementsByTagName("head")[0].appendChild(script); //第2步,载入js文件后 // 定义被脚本执行的回调函数,getJSON[name]这里要作为一个变量,所以要用[],而不能用. getJSONP[name]=function(data){ //第3步:执行url中指定的函数 try{ //try里面是可能发生错误的;比如跨域获取没有成功或成功 callback&&callback(data); }catch(e){ //发生错误了可以捕获到 // }finally{ //不管有没有发生错误,都要执行的操作 //最后删除该函数及script标签,不删除的话产生数据会造成污染 delete getJSONP[name]; script.parentNode.removeChild(script); } } } } getJSONP(url,function(data){ console.log(data); //这里的回调函数传到getSONP函数里面,在getJSONP[name]函数执行,getJSONP[name]函数传回来了跨域的数据data,所以最后将data传出来并打印 });