跨域的安全限制都是对浏览器端来讲的,服务器端是不存在跨域安全限制的。html
浏览器的同源策略限制从一个源加载的文档或脚本与来自另外一个源的资源进行交互。web
若是协议,端口和主机对于两个页面是相同的,则两个页面具备相同的源,不然就是不一样源的。ajax
1 flash (已经淘汰)json
2 服务器代理中转跨域
3 jsonp 是数据交换的协议浏览器
4 document.domain(针对基础域名相同的状况)安全
如服务器
bj.58.com document.domain = 58.comapp
tj.58.com document.domain = 58.comdom
针对jsonp 解决跨域问题:
5 iframe 实现跨域
1 web页面中拥有"src"属性的标签都拥有跨域的能力,好比<script> <image><iframe>
2 因此,咱们将数据放到服务器上,而且数据为json格式,(由于js 能够轻松处理json数据)
3由于咱们没法监控经过script 的src属性是否把数据获取完成,因此须要作一个处理
4实现定义好处理跨域获取数据的函数,如function doJSON(data){};
5用src获取数据的时候添加一个参数cb='doJSON'(服务端会根据参数cb的值返回对应的内容)
此内容为以cb对应的值doJSON为函数真实要传递的数据为函数的参数的一串字符 如doJSON('数据');
最简单的原理,例如:
var oScript= document.createElement('script'); oScript.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=Anderson_An&cb=fn'; document.body.appendChild(oScript); //声明请求数据成功后执行的函数 function fn(data){ console.log(data); }
ajax 实现数据请求不能跨域,jsonp能够实现跨域获取数据
本质区别是二者实现的原理不一样:ajax 是经过建立xmlHTTPRequest 来获取内容,
而jsonp 的实现原理是经过,动态的添加script标签,利用src属性调用js 脚本实现;
一个小栗子实现跨域获取百度智能输入提示的功能:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ padding: 0; margin: 0; } #box { margin: 100px; } #wd{ width: 400px; height: 40px; } #list{ display: none; width: 400px; border: 1px solid #ccc; } li{ list-style: none; padding: 5px; } a{ text-decoration: none; color: #333; } </style> </head> <body> <div id="box"> <input type="text" id="wd"> <ul id="list"></ul> </div> <script> var wd = document.getElementById('wd'); var oUl = document.getElementById('list'); wd.oninput = debounce(getUserAction, 100, false);//给输入绑定一个防抖事件 function debounce(func, wait, immediate) { var timer = null; var result; var debounced = function () { var _this = this; var argu = arguments; clearTimeout(timer); if(immediate) { if(!timer) func.apply(_this, argu); timer = setTimeout(function () { timer = null; }, wait) }else { timer = setTimeout(function () { func.apply(_this, argu); }, wait) } return result; } debounced.cancel = function () { clearTimeout(timer); timer = null; } return debounced; } function getUserAction() { if(wd.value) { var oScript = document.createElement('script');//建立一个script标签 oScript.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=' + wd.value +'&cb=doJson'; document.body.appendChild(oScript); document.body.removeChild(oScript); }else { oUl.style.display = 'none'; } } function doJson(data) { var dataList = data.s;//由于百度的提示字符保存在s下 oUl.innerHTML = ''; if(dataList.length == 0) { oUl.style.display = 'none'; }else { dataList.forEach(function(item, index) { var oLi = document.createElement('li'); var oA = document.createElement('a'); oA.href = 'https://www.baidu.com/s?wd=' + item; oA.innerText = item; oLi.appendChild(oA); oUl.appendChild(oLi); oUl.style.display = 'block'; }) } } </script> </body> </html>
另外iframe 实现跨域
建立iframe 引用src 时末尾加一个' # '后面跟对应的要传的值;
获取方式:location.hash 就能够获取