- JSONP跨域实现原理
- 百度联想词跨域实现
一、JSONP跨域实现原理
1.Web页面使用<script>引入JS文件时不受同源策略的影响。准确的说,所有拥有src属性的标签都不受同源策略的影响,都具备跨域的能力。比如script、img、iframe。
2.JS脚本被加载后都会被浏览器内核从上到下解析执行一遍。
3.但是因为网络请求是浏览器内核异步执行,无法掌握异步加载的脚本的加载状况。所以,需要将资源传入一个立即执行的回调函数。
4.在全局JS资源上定义一个回调函数,用来处理传入的资源。
5.在通过src获取数据的时候,将全局JS上的回调函数名作为请求变量值传入。
6.后台将数据与回调函数名拼接成一个立即执行的字符串形式,当数据全部传送到后执行。
//处理jsonp数据的回调函数 var doJSONP = function(data){ console.log(data.a); } //采用添加script获取外部资源 function jsonp(){ var value = this.value; var oScript = document.createElement("script"); oScript.src = "http:xxx.com/index.php?cb=doJSONP"; document.body.appendChild(oScript); oScript.remove(); }
在后台数据拼接成字符串形式:
'doJSONP({a:"123"})'
二、百度联想词跨域实现
<input type="" name="" class="jsonpInput" /> <ul class="assList"></ul> <script > //添加事件的公共方法 function addEvent(elem,type,handle){ if(elem.addEventListener){ elem.addEventListener(type,handle,false); }else if(elem.attachEvent){ elem.attachEvent('on' + type, function(){ handle.call(elem); }); }else{ type = type.substring(0,1).toUpperCase()+type.substring(1); elem['on' + type] = handle; } } //回调函数(拿到数据新增列表项) var doJSONP = function(data){ var s = data.s || []; assList.innerHTML=""; if(s.length > 0){ try{ s.forEach(function(ele,index){ var aNoHTML = document.createElement("a"); aNoHTML.href = "https://www.baidu.com/s?wd="+ ele; aNoHTML.target = "_blank"; aNoHTML.innerHTML='<li>' + ele + '</li>'; addEvent(aNoHTML,"mouseup",function(){ assList.style.display = "none"; }); assList.appendChild(aNoHTML); if(index > 3){ var a = aaaaa; //引用try报错机制跳出循环 throw new Error("ending"); } }); }catch(e){ } assList.style.display = "block"; }else{ assList.style.display = "none"; assList.innerHTML=""; } } //获取input、ul标签 var jsonpInput = document.getElementsByClassName("jsonpInput")[0]; var assList = document.getElementsByClassName("assList")[0]; //添加input事件 addEvent(jsonpInput,"input",function(){ var value = this.value; var oScript = document.createElement("script"); oScript.src = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=" + value +"&cb=doJSONP"; document.body.appendChild(oScript); oScript.remove(); } ); </script>
百度的连接可能会修改。